Hello,
I see that the function FindUninitializedScriptStructMembers finds and reports uninitialized UStruct properties during the engine initialization. I see no equivalent for properties in UClass and I am wondering why it does not exist. Is it an oversight? Or maybe there is a technical reason behind it?
Thank you,
Clement
[Attachment Removed]
Hi,
UObjects can only be created via a CoreUObject function like NewObject or StaticConstructObject, and these functions zero the target memory of the UObject before running its constructor. This causes uninitialised members without a default constructor to have a zero bit pattern, which in almost all cases (*) is the desired behaviour: pointers become null, bools become false, ints and floats become zero.
This also includes uninitialised UStruct properties which are properties of UStructs, so would not be a problem in that case, but the function you mention exists because a common thing to do is construct a UStruct on the stack - which is not zeroed by default - then copy it into your UObject property, like:
USTRUCT()
struct FMyStruct
{
GENERATED_BODY()
UPROPERTY()
int32 X = 0;
UPROPERTY()
int32 Y = 0;
UPROPERTY()
int32 Z; // oops
};
UCLASS()
class UMyObject : public UObject
{
GENERATED_BODY()
public:
UMyObject();
UPROPERTY()
FMyStruct MyStruct;
};
UMyObject::UMyObject()
{
// Override some values
FMyStruct LocalStruct;
LocalStruct.Y = 5;
// LocalStruct.X is initialised to zero, but LocalStruct.Z is uninitialised
MyStruct = LocalStruct; // copy uninitialised junk back into object
}
This is why UStructs in particular are checked.
Hope this is clear,
Steve
(*) One instance where this isn’t the case is pointer-to-data-member types, where a zero bit pattern is *not* typically a null pointer, because they’re not really pointers. But as these are pretty much never used as UObject members, it’s not really an issue. See the difference here: Compiler Explorer
[Attachment Removed]
It is very clear, thank you for the thorough answer.
Clement
[Attachment Removed]