Error trying to forward declare a ustruct?

I’m trying to forward-declare a custom ustruct like this in a different class:

struct FArmyPresetStruct;

public:

UFUNCTION()
void LoadArmy(FArmyPresetStruct);

I include the directive that has the definition of the struct in my implementation file, but I’m getting an error that I’m using an undefined struct. Is there a way to fix this?

Thanks in advance!

Hi ThatNerdFury,

If you use a pointer (FArmyPresetStruct* myptr) it will work - it doesn’t need to know the class definition then.

2 Likes

Also:

1 Like

If you use a pointer (FArmyPresetStruct* myptr) it will work - it doesn’t need to know the class definition then.

I get an error saying “cannot have an exposed pointer to this type.”

You don’t forward declare USTRUCT’s. Just put them all your relevant USTRUCTs in a header file, like “ArmyTypes.h” and include that.

UCLASS is a reference type. They’re passed by reference, and garbage collected when no more references (strongly) point to them.

USTRUCT is a value type. They can certainly be passed by reference or pointer, but fundamentally they’re more like a memory block that’s always passed around by value. Thus they’re not garbage collected. When the compiler is dealing with a value type it needs to know all about the type to implement it. Reference types are passed by reference, the compiler doesn’t need to know much about the type to just handle references to it.

I’m sure this is all “clear as mud”, but USTRUCTs just fully declare them in in their own header file and avoid circularity, clean and simple.

5 Likes

I have the struct defined in a separate header, but I wanted to avoid putting dependencies in the header because it feels cleaner and is faster, so I just wanted to include the file in the .cpp when it’s actually used. But since I use it as a parameter in a function declared in my header, I was hoping there was a way to avoid having to include the entire file in my header, if that makes sense?

1 Like

You can not avoid this unless the parameter is a pointer or reference.

You can not avoid this unless the parameter is a pointer or reference.

But I’m getting an error saying I can’t make it a pointer.

What about as “LoadArmy(struct FArmyPresetStruct& myRef)” ?

Yes I’m just adding the information to what has been posted already, since you asked :stuck_out_tongue: .

Yeah, you can’t pass a pointer to a USTRUCT into a UFUNCTION. That’s because structures are not garbage collectable. So, the unreal header tool disallows passing them by pointer to UFUNCTIONs.

Epic hasn’t exposed smart pointers to UFUNCTIONs (TSharedPtr, etc), so they’re out.

The only thing left is to forward declare it and pass by reference. As far as C++ goes this should work (in theory)… But Unreal Header Tool chokes when it encounters a reference to an incomplete type.

The error:
error : Attempt to fetch the generated hash for type “FArmyPresetStruct” before it has been generated. Include dependencies, topological sort, or job graph is in error.

Meaning, there’s not much you can do but fully declare the struct if you want to pass it into a UFUNCTION…

(Even in the LoadArmy(struct FArmyPresetStruct& myRef) form)

1 Like