UFunction incorrect param size?

I made a test function in blueprints to call it via c++ Uproperty / ufunction reflection code after discovering it by name.

The function in Blueprint has only two parameters , bool and float.

now sizeof(bool) returns 1 and sizeof(float) returns 4, which is correct.

but Function->ParmsSize returns 8 ! Why is that? bool should be 1 so ParamSize must be 5 not 8.

This was further confirmed when I had to pad the remaining 3 bytes for bool param otherwise the float paramter would be misaligned in the params pointer.

So why is a bool reported 4 bytes in ParmsSize am I using wrong method to figure out size of the property in Ue4 environment?

Further testing tells me that minimum param size is 4 because even byte reports a param size of 4

The C++ variable types are only valid in compilation time, after that only types that CPU knows is integers and floating points (and vectors if you think about MMX and SSE instructions) and it can not distinguish them as memory are just sequence addressable 8-bit bytes. While CPU don’t know what Boolean is and Boolean it self can’t be really addressed directly as one, depending how compiler treats them are usually hold as bits in uint8 and use bit manipulation instructions to operate them, but in run time they can also be helt as bit fields in multiple bytes for optimization.

Since we talking here about function in virtual machine of Blueprints, there no guaranty it types will be used same way as C++ does, specially that in runtime you can do more optimized operation on bit fields. C++ single bool can only at least in single byte, as otherwise it would conflict with concept of pointer and bool use with them as well as casting to different types and use if void*, as bool primitive can’t hold information which bits are used and that information can not be retrived on runtime in any way. While virtual machine that can deal with memory management on runtime and have reflection system that store information about varables can, so it can hold multiple bool variables in bit fields to save up space, so blueprint hold bool in groups in few bytes, instend wasting memory to hold single bool in single byte

By your discovery that means for some reason blueprints use 32bit bit field to hold booleans properties by default, there might reason behind that choose, for example to make CPU process and virtual machine overall them faster.

Looking on UBoolProperty class code it seem to be the case as code is ready to support both native bools the way they are compiled (since compiler will treat UBoolProperty class same way as any other class, UBoolProperty can figure out how they gonna be packed) and bit fields from 8 to 64 bit bit fields created by blueprints and class it self tracks the size and and bit mask used.

https://github.com/EpicGames/UnrealEngine/blob/b70f31f6645d764bcb55829228918a6e3b571e0b/Engine/Source/Runtime/CoreUObject/Private/UObject/PropertyBool.cpp#L43

There even function to set the size of field ;p

Note that UFunction is inherented as UStruct and arguments information are helt same way as UStruct and UClass so to be save, depend on UProperty of arguments information insted of sizeof, if you dealing with functions not anchored to C++. Since again virtual machine of any kind might deal with types differently then C++ compiler.

Also note that blueprint only support one type of integer which is int32 and might be also argument behind that choose including for blueprint Byte type, so Byte might be only there for compatibility with some functions and structures (like FColor for example) and other integer types are less frequently used and skipped to spear programmers that come from higher languages from byte size confusion. If Byte don’t orginate from C++ it treats it same way as int32

Specifically in this case it’s because the function parameters are stored as UStruct, so are subject the padding and alignment as any other data members would be (float needs to be 4-byte aligned, hence the padding).

If you’re dealing with reflected data, always make sure and get/set it via UProperties rather than trying to guess the layout yourself. There’s loads of examples in the Python plugin of using reflection to call a UFunction correctly.