Using macros cannot resolve recursive references either.
-
I have three files: classA.h, classB.h, and all_header.h. The details are as follows:
//classa.h #ifndef CLASSA_H #define CLASSA_H #include"all_header.h" class ClassA { public: ClassA(); ClassB b1; }; #endif
//classb.h #ifndef CLASSB_H #define CLASSB_H #include"all_header.h" class ClassB { public: ClassB(); ClassA* a1; }; #endif // CLASSB_H
//all_header.h #ifndef ALL_HEADER_H #define ALL_HEADER_H class ClassA; class ClassB; #include"classb.h" #include"classa.h" #endif // ALL_HEADER_H
During compilation, the following error occurs:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'However, when I use the above structure in a standard C++ compiler (whether MSVC or MinGW), it works fine.
So, why does this happen? -
I have three files: classA.h, classB.h, and all_header.h. The details are as follows:
//classa.h #ifndef CLASSA_H #define CLASSA_H #include"all_header.h" class ClassA { public: ClassA(); ClassB b1; }; #endif
//classb.h #ifndef CLASSB_H #define CLASSB_H #include"all_header.h" class ClassB { public: ClassB(); ClassA* a1; }; #endif // CLASSB_H
//all_header.h #ifndef ALL_HEADER_H #define ALL_HEADER_H class ClassA; class ClassB; #include"classb.h" #include"classa.h" #endif // ALL_HEADER_H
During compilation, the following error occurs:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'However, when I use the above structure in a standard C++ compiler (whether MSVC or MinGW), it works fine.
So, why does this happen? -
I have three files: classA.h, classB.h, and all_header.h. The details are as follows:
//classa.h #ifndef CLASSA_H #define CLASSA_H #include"all_header.h" class ClassA { public: ClassA(); ClassB b1; }; #endif
//classb.h #ifndef CLASSB_H #define CLASSB_H #include"all_header.h" class ClassB { public: ClassB(); ClassA* a1; }; #endif // CLASSB_H
//all_header.h #ifndef ALL_HEADER_H #define ALL_HEADER_H class ClassA; class ClassB; #include"classb.h" #include"classa.h" #endif // ALL_HEADER_H
During compilation, the following error occurs:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'However, when I use the above structure in a standard C++ compiler (whether MSVC or MinGW), it works fine.
So, why does this happen?@kuqipair said in Using macros cannot resolve recursive references either.:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'
ClassA::b1 returns ClassB, not ClassB* - this cannot work with forward declaration!
-
I have three files: classA.h, classB.h, and all_header.h. The details are as follows:
//classa.h #ifndef CLASSA_H #define CLASSA_H #include"all_header.h" class ClassA { public: ClassA(); ClassB b1; }; #endif
//classb.h #ifndef CLASSB_H #define CLASSB_H #include"all_header.h" class ClassB { public: ClassB(); ClassA* a1; }; #endif // CLASSB_H
//all_header.h #ifndef ALL_HEADER_H #define ALL_HEADER_H class ClassA; class ClassB; #include"classb.h" #include"classa.h" #endif // ALL_HEADER_H
During compilation, the following error occurs:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'However, when I use the above structure in a standard C++ compiler (whether MSVC or MinGW), it works fine.
So, why does this happen?@kuqipair
In addition to @Pl45m4 [I posted this before @jsulm's response]During compilation, the following error occurs:
However, when I use the above structure in a standard C++ compiler (whether MSVC or MinGW), it works fine.
What does the first line mean? You must have used a "standard C++ compiler" when you got the error, but then you say that in a "standard C++ compiler" it works fine... ?
-
@Pl45m4 In both classA. h and classB. h, directly referencing the all_ceader. h file achieves the effect of forward declaration. However, when I do this on QT, I encounter compilation errors.
@kuqipair said in Using macros cannot resolve recursive references either.:
However, when I do this on QT, I encounter compilation errors.
There is no "Qt"... You use a "standard C++ compiler" when using Qt in your project...
Also check as @jsulm pointed out:@jsulm said in Using macros cannot resolve recursive references either.:
lassA::b1 returns ClassB, not ClassB* - this cannot work with forward declaration!
-
@kuqipair said in Using macros cannot resolve recursive references either.:
error: C2079: 'ClassA::b1' uses undefined class 'ClassB'
ClassA::b1 returns ClassB, not ClassB* - this cannot work with forward declaration!
@jsulm I implemented this in a QT project. I wanted classA.h and classB.h to directly include the all_header.h file to achieve the effect of forward declarations, but this caused compilation failures. However, when I used the same approach in a regular C++ project compiled with both MSVC and MinGW compilers, it worked successfully.
-
@jsulm I implemented this in a QT project. I wanted classA.h and classB.h to directly include the all_header.h file to achieve the effect of forward declarations, but this caused compilation failures. However, when I used the same approach in a regular C++ project compiled with both MSVC and MinGW compilers, it worked successfully.
-
@kuqipair
Then start by comparing the exact compilation lines executed in the Qt and non-Qt case, to see where the difference is.@JonB Ah-ha, I figured it out!
I consulted DeepSeek-R1, and it suggested explicitly defining the precompiled header in the .pro file like this:PRECOMPILED_HEADER = all_header.h CONFIG += precompile_header
Big thanks to the amazing open-source AI models from my great motherland (China) - they're truly phenomenal! Highly recommended!
-
@JonB Ah-ha, I figured it out!
I consulted DeepSeek-R1, and it suggested explicitly defining the precompiled header in the .pro file like this:PRECOMPILED_HEADER = all_header.h CONFIG += precompile_header
Big thanks to the amazing open-source AI models from my great motherland (China) - they're truly phenomenal! Highly recommended!
-
No need for some obscure AI here - simply fix your project structure to avoid recursive includes as this is a big sign for a design flaw. Also use forwarding of classes instead direct includes to reduce compile times.
-
Headers alone don't do anything. Suppose you have a
classb.cpp
that just includesclassb.h
. This header first declares the macroCLASSB_H
. Then you go on to includeall_header.h
fromclassb.h
. This first includesclassb.h
followed byclassa.h
. However, when includingclassb.h
fromall_header.h
(included fromclassb.h
)CLASSB_H
is already defined and the inclusion returns nothing. So far,ClassB
has not been defined. Then you go on includingclassa.h
which expects a full definition ofClassB
.This problem only occurs when including
classb.h
(before any of the other two headers). It is not a problem when includingclassa.h
orall_header.h
(first). Usingall_header.h
as a pre-compiled header will includeall_header.h
before everything else in every translation unit. That's why this solution works. But IMHO this is not a proper solution because source code should always also compile without precompiled headers. Especially in this scenario a change in ClassA or ClassB will trigger a recompile of the precompiled header and thus a recompile of your whole project. This is not a tenable solution for large projects. Precompiled headers should be reserved for third-party libraries that (almost) never change. It is not meant for your own source code. (Precompiled headers are supposed to reduce compilation times and not increase them.)I am not sure what a good solution to this problem is. Most likely it works by removing the include guards for
all_header.h
. I believe these are (in this specific context) not actually needed.