Hey everybody,
I am working with UE for a few month now and already archieved some good results. I have a basic understanding of how things work in C++ but I am not a hard core programmer.
So now my problem I had to deal with a couple of times:
Sometimes in my project I need to include some headers in each other like this:
Normaly no problem thanks to #pragma once #ifndef HEADERONE_H #define HEADERONE_H
… #endif DBG_HEADERONE_H
Same for headerTwo.h
This worked quiet well, when I had two “empty” classes in which there was defined a value of the typ of the other class. But now several times I needed to do this with actor classes defined like this:
… #include “GameFramework/Actor.h” #include “SomeActor.generated.h”
UCLASS()
class SOMEPROJECT_API ASomeActor : public AActor
{
GENERATED_BODY()
…
But if I try to deal with it like in the example above, I get “error : UCLASS inside this preprocessor block will be skipped”
Just #pragma once does not work and with out UCLASS it also worked in another case. But now I need the Tick event and there fore UCLASS().
Is this an issue of UE or maybe Visual Studio (I am using Community 2017) or am I just stupid?
Can anybody help me please?
Thanks Robbi
(please excuse mistakes in my english)
Just use #pragma once. It does what the #ifndef/#define stuff does automatically. When you use #ifdef/#ifndef inside UE4 C++ code it confuses UBT – though UBT has its own defines that you can use in the preprocessor.
When compiling code, visual studio will analyze it. If there are no usages of a dll or your code, even if it is included, it will completely ignore it.
Since you said that your classes are empty right now I can assume just that. The solution would be to reference it elsewhere in code. Even if you don’t utilize it, VS will see that and not ignore your code.
At first thanks for your fast answer, but as alredy discribed above #pragma once alone does not work. Can you please tell me which defines in UBT you are talking about? I also added a more specific example to my question.
Ok mabee I need to give more detail. I did something similar to this:
HeaderA: #pragma once #ifndef HEADERA_H #define HEADERA_H
#include “HeaderB.h”
class AHeaderB; // let the compiler know, that it exists
class AHeaderA
{
public:
AHeaderA();
private:
AHeaderB *valueB;
} #endif HEADERA_H
and opposite for HeaderB. I do not think I have to write it our
So this works fine but just WITH #ifndef. Just #pragma once gives me error LNK2005. Confusing.
Also works if I set valueB to const, but thats no solution.
Again thanks to everyone who tries to help. Robbi
At Jin_VE
Why ever I can not reply to your answer anymore (mybee because the question is resolved) I will do it here:
Thank you so much for your time and have a nice weekend
You are defining settingTest in the header and it is being included in multiple .cpp files so they all have their own instance and the names are conflicting. In general, with UE4 you should avoid using global variables. You should put ‘global’ things in the GameMode, GameState, PlayerState, or one of a few other places.
That said, to get what you have to compile:
In the .h file, change it to extern int settingTest;
In one of the .cpp files, use int settingTest = 0;
Ok, it actually does work with out #ifndef, I do not know why I thought it would not, sorry for that. So I tried to reproduce the LNK2005 error. I have created 5 files for this:
TestActor.h
This is now every line of code. When i try to compile, I get this:
2>TestActor.cpp.obj : error LNK2005: "int settingTest" (?settingTest@@3HA) ist bereits in SeccondActor.cpp.obj definiert.
2>SeccondActor.gen.cpp.obj : error LNK2005: "int settingTest" (?settingTest@@3HA) ist bereits in SeccondActor.cpp.obj definiert.
2>TestActor.gen.cpp.obj : error LNK2005: "int settingTest" (?settingTest@@3HA) ist bereits in SeccondActor.cpp.obj definiert.
2>TestActor.cpp.obj : warning LNK4006: "int settingTest" (?settingTest@@3HA) ist bereits in "SeccondActor.cpp.obj" definiert; zweite Definition wird ignoriert.
2>SeccondActor.gen.cpp.obj : warning LNK4006: "int settingTest" (?settingTest@@3HA) ist bereits in "SeccondActor.cpp.obj" definiert; zweite Definition wird ignoriert.
2>TestActor.gen.cpp.obj : warning LNK4006: "int settingTest" (?settingTest@@3HA) ist bereits in "SeccondActor.cpp.obj" definiert; zweite Definition wird ignoriert.
“ist bereits in … definiert” means “is already defined in …” and “zweite Definition wird ignoriert” means “seccond defenition will be ignored”.
I even do not use “settingTest” but still get the error. What is going on there and how to prevent it?
Jap, tested it out, works fine. Not the answer I was hoping for but the answer on my question. You explaned what happens there so I think I can mark this as resolved. With this information I will have to think about the structure of my work again.
Thank you for your time and have a nice weekend. Robbi
I ran into the same issue with my plugin. It’s very limiting to not be able to specify conditional blocks of code. But UBT (UHT in this specific case) isn’t a compiler, it just scans and generates intermediate source code. It can’t consider compile-time directives without compiling. That’s fair IMO.