UPROPERTY Variable Naming Collisions

Hello, for some reason you can’t name a variable that has a UPROPERTY with the same name as a struct that i define (without the F prefix). Example:

USTRUCT()
struct FAmmoTypeDefaults
{
...
};

If i have on my class this:

UPROPERTY(EditDefaultsOnly, Category = "Test")
TArray<FAmmoTypeDefaults> AmmoTypeDefaults;

It will say:

Member variable declaration: 'AmmoTypeDefaults' already defined	

On Server and client functions i can’t use names for the parameters like FRotator Rotator, or other variable names that i have defined on other classes. Example:

On my item class i have a int32 Quantity variable, if i declare a server function (it might not even be on the same class or file) with a parameter int32 Quantity it will say:

Function parameter: 'Quantity' conflicts with previously defined field in 'Item'

Can you please explain why does this happen and if it’s really a bug. Thank you.

Can you provide a sample simple/blank project that demonstrates the issue? This helps with testing, but also allows you to verify if it’s a problem with your specific project.
Information regarding which UE version and if it’s a source/launcher build you’re using would be helpful, too.

I’m using 4.5.1 source code build. To replicate the first i did the following:

  • Create a fresh c++ First Person Template

  • On the Character header i put this above the class declaration:

    USTRUCT()
    struct FAmmoTypeDefaults
    {
    GENERATED_USTRUCT_BODY()

     UPROPERTY(EditDefaultsOnly, Category = "Ammo Type Defaults")
     int32 Test;
    

    };

and on the class i put this:

UPROPERTY(EditDefaultsOnly, Category = Projectile)
TArray<FAmmoTypeDefaults> AmmoTypeDefaults;
  • I got the following error:

    Member variable declaration: ‘AmmoTypeDefaults’ already defined


For the second issue i used the same project and did the following steps:

  • Added this to the class header:

    UPROPERTY(EditDefaultsOnly, Category = Projectile)
    int32 Quantity;

    public:

     UFUNCTION(NetMulticast, Reliable)
     void ClientTest(int32 Quantity);
    
  • Added this to the class cpp:

void AMyProjectCharacter::ClientTest_Implementation(int32 Quantity)
{

}

  • I got the following error:

Function parameter: ‘Quantity’ conflicts with previously defined field in ‘MyProjectCharacter’

UHT (UnrealHeaderTool) generates code based on dummy macros like UPROPERTY (they do nothing during compilation) and rest of the header file code (function names etc.), that code is for reflation system and other fancy features you see in UMACROs making UE4 coding a lot easier. So your code collides with generated code, whatever this is bug depends if you consider rules forced by UHT as conventions. Btw you can find generated code somewhere in Intermidite directory in your project directory

Yes I assumed that, but it’s a bit of a bummer not being able to name variables the way you want, to maintain consistency :stuck_out_tongue: I would like to know if Epic plans on leaving it like this or are they thinking about changing something like putting prefix or suffixes (like GEN_) so it has less probability of colliding.

Yeah, well, I just got hit by this same thing, two years later. So I guess the answer is not.

It is a huge bummer. I sometimes want to use things like:

UCLASS()
class UMyStuff : public USomeStuff {
 //
 UPROPERTY()
 UImportantsStuff *ImportantStuff;
 //
 UFUNCTION()
 void HandleStuff(UImportantStuff *ImportantStuff)
}

, so as to not put any semantic in code that doesn’t need it. Now I have to user weird conventions à-la Objective-C. Ugh!

Hey Heroico-

Due to the way that the Unreal Build Tool processes Unreal classes, it does not differentiate between the names of UPROPERTYs and the names of parameters of UFUNCTIONs. If the same name is used for a variable and a function parameter, the compiler will think that you are declaring the same variable twice. This is an unfortunate limitation of Unreal classes.

If either the variable or the parameter is not defined as being a UPROPERTY or part of a UFUNCTION, then this should not be a problem.