How to fix a Syntax Error on variable declaration of custom class?

Im trying to declare a ADMagicCharacter variable in Spell.h, as seen below.

IntelliSense shows everything is fine, but during compile it throws a syntax error at ADMagicCharacter Caster;*

" error C2143: syntax error : missing ‘;’ before ‘*’ "

I can’t figure out the problem, as It appears that everything is correct?
Please let me know if Im missing something, as Im at a loss…

Spell.h

#pragma once

#include "GameFramework/Actor.h"
#include "DMHeaderList.h"
#include "Spell.generated.h"

...

UCLASS()
class DMAGIC_API ASpell : public AActor
{
	GENERATED_BODY()
	
public:	
	
	// Sets default values for this actor's properties
	ASpell(const FObjectInitializer& ObjectInitializer);

...
	ADMagicCharacter* Caster;

...
	UPROPERTY(VisibleAnywhere, Category=Spells)	AProjectile* SpellProjectile;

...

};

DMagicCharacter.h

#pragma once

#include "GameFramework/Character.h"
#include "DMHeaderList.h"
#include "DMagicCharacter.generated.h"

...

UCLASS(config=Game)
class ADMagicCharacter : public ACharacter
{
	GENERATED_BODY()

...

public:
	ADMagicCharacter(const FObjectInitializer& ObjectInitializer);

...

};

DMHeaderList.h

#pragma once
#include "Engine.h"
#include "DMagicGameMode.h"
#include "DMagicCharacter.h"
#include "Spell.h"
#include "Projectile.h"

While it may seem like you DMHeaderList.h has the right ordering, the error seems to be that at the time Spell.h is compiled it doesn’t understand what ADMagicCharacter is.

It is probably because of the circular dependency in your headers. DMHeaderList.h includes Spell.h which includes DMHeaderList.h.

In this case you can forward declare your used of the ADMagicCharacter. Simple add the word “class” in front of your member variable, or better yet put “class ADMagicCharacter” right below your include files and above the class declaration.

Additionally, something to remember, is ALWAYS use UPROPERTY above UObject member variables or you will have garbage collection issues. Your Caster variable will be set to null on the first opportunity to garbage collect and you’ll crash if you access it. Or at least you will get bad behavior.

Spell.h

#pragma once

#include "GameFramework/Actor.h"
#include "Spell.generated.h"


...
// Forward declarations here (as long as its pointer type or const& and you don't need the internal details this will be fine)
// any time you use the implementation of the class, put it in the cpp and include DMagicCharacter.h there 
class ADMagicCharacter;
class AProjectile;

UCLASS()
class DMAGIC_API ASpell : public AActor
{
	GENERATED_BODY()
	
public:	
	
	// Sets default values for this actor's properties
	ASpell(const FObjectInitializer& ObjectInitializer);

...
	UPROPERTY()
    ADMagicCharacter* Caster;

...
	UPROPERTY(VisibleAnywhere, Category=Spells)
AProjectile* SpellProjectile;

...

};

DMagicCharacter.h

#pragma once

#include "GameFramework/Character.h"
#include "DMagicCharacter.generated.h"
//try to only include what you use  
//DMHeaderList.h is going to get too big and cause you future headache

...

UCLASS(config=Game)
class ADMagicCharacter : public ACharacter
{
	GENERATED_BODY()

...

public:
	ADMagicCharacter(const FObjectInitializer& ObjectInitializer);

...

};

DMHeaderList.h

#pragma once
#include "Engine.h"
#include "DMagicGameMode.h"
#include "DMagicCharacter.h"
#include "Spell.h"
#include "Projectile.h"

Thank you, adding class in front of the ADMagicCharacter declaration solved the issue.
Will circular dependency mess with the project? (aside from syntax errors like this. I mean at run time)

Circular dependencies will always result in a compile error of some kind. The issue is that the compiler is looking for the complete definition of something before it can consider it compilable. If it has to go figure out the definition of something else to understand part of the first thing and that second thing is defined in terms of the first, you can’t resolve that.

Here is a link on the concept if you would like more information

It may not be that obvious as that, and in fact just using includes can run the compiler in circles, as was your case.

A.h

#include "B.h"
class A
{
   public:

   B*  MyB;
};

B.h

#include "A.h"
class B
{
  public:
  A*  MyA;
};

As defined, and pardon the bad pseudocode, the compiler could never resolve this because it would just bounce back and forth. One of them has to be resolveable before it can move on.

NewA.h

class NewB;

class NewA
{
   public:

   NewB*  MyB;
};

NewB.h

class NewA;

class NewB
{
  public:
  NewA*  MyA;
};

“Additionally, something to remember, is ALWAYS use UPROPERTY above UObject member variables or you will have garbage collection issues.”

Wait, there is a difference between:

UPROPERTY(VisibleAnywhere, Category=Spells) float fVar;

and:

UPROPERTY(VisibleAnywhere, Category=Spells)
float fVar;

?

That kind makes a mess of my variable declarations…

Or are you just saying to add a UPROPERTY to just class declarations like ADMagicCharacter and AProjectile?
It would seem rather messy and disorganized to have to tack that onto every float and int…

You should read up on UObjects and the reflection system (UPROPERTY, UFUNCTION, etc).

UE4 Relection System blog entry

I wasn’t commenting on your formatting, either of your statements above are fine. What is important is that any UObject member variables of a class must be marked as UPROPERTY otherwise your memory will be freed up by the engine. UObject memory management is done by garbage collection and it only knows the object is in use if it can follow UPROPERTY variables. There are internal lists of objects and if other objects don’t tell that main list they are using something via UPROPERTY the object will be removed out from under you.

There are lots of powerful things that require UPROPERTY. You don’t have to mark every variable as one, but if you want to replicate over the network, save to disk, edit the value in the editor, debug print variable state, etc you must have them marked.

Some other links I’ve shared in the past

Intro C++ in UE4

Understanding MyClass.generated.h files

Programming Docs

Objects/Actors/Framework

Programming Quick Start

Replication