Skip to main content
GameDev.net gamedev.net
🔒 Locked

Circ Dependency hell [Solved]

Started by Burnt_Fyr Oct 27, 2010 at 3:50 PM 15 replies 2.1k views
Original Post
Burnt_Fyr
Burnt_Fyr
Why do I always run into these when I've had little sleep and less coffee:

// a.hclass b; // forward declarationinclude "b.h" //b.hclass a; // forward declarationinclude "a.h"include "c.h" //error c2079//c.hinclude "a.h 


issue is due to inclusion of c.h in b.h, if not for that project compiles fine. What must be declared to use a reference to an instance of C in B

[Edited by - Burnt_Fyr on October 27, 2010 8:34:55 PM]
DimitriA
DimitriA
example header

main.h
#ifndef GUARDMAIN_H#define GUARDMAIN_H... put code here ...#endif


now you can include main.h as many times as you want

#include "main.h"#include "main.h"#include "main.h"#include "main.h"


You just need to use compiler directives so that it won't include the same content twice

Whats happening?

#ifndef is pretty much 'if not defined', so in this case its looking for token GUARDMAIN_H, if its not found then it proceeds with reading and compiling the code - its only processed during compile time (I think they're called Compiler Directives)

#define GUARDMAIN_H - just defining the token

#endif - and ending the #ifndef

I think you could also use #pragma once - but I'm not too sure about that

*edit* Yeah you can use #pragma once, it seems it has had some history!
Burnt_Fyr
Burnt_Fyr
Lol, was not expecting this for a response. I'm well aware of include guards but didn't include(lol) them for the sake of brevity. I get a C2079, not C2011, which I had originally included in the title, but decided against obscure numbers.
DimitriA
DimitriA
Ahh sorry about that,

I think you can do an extern class b //edit just tested and doesn't seem to be the case.

Though if not, you will just have to include b.h in c.h also - if I read right.

eta: Why would c++ have any form of brevity? :p
Burnt_Fyr
Burnt_Fyr
Extern creates a static instance, not what i'm looking for, and i don't think it will help anyway. Generally I don't post until I've exhausted all other options, and b in c didn't work, nor any other permutation i've thought of.
DimitriA
DimitriA
Give this link a try http://msdn.microsoft.com/en-us/library/9ekhdcxs%28VS.80%29.aspx
Burnt_Fyr
Burnt_Fyr
I've hit that link already,

// C2079d.cppclass A;class C {}; //C doesn't need A, unlike my situationclass B {   A * a;   C c;};class A {}; // Ditto, A doesn't reference B, so doesn't include b,


even though your suggestions as yet haven't helped, I very much appreciate them. Keep them coming;
SiCrane
SiCrane
You can use a forward declaration for references.
Burnt_Fyr
Burnt_Fyr
With FD's only and NOT including C.h in b.h i get :

b.h(xxx) : error 2027: use of undefined type 'c'b.h(xxx) : error C2228: left of '.c_member_property' must have class/struct/union


Is the issue that I'm trying to use member data from C in a function of b? these are all low level utility classes with no private data of there own.

I could always make a global function:
BFunctionThatDependsOnInstanceOfC( C _c) but have been trying to avoid this as much as possible.

SiCrane
SiCrane
Well, the obvious solution would be to move the function definition from the header to a source file.
rip-off
rip-off
You cannot call member functions of forward declared classes. The compiler must see the function declarations to preserve the type system and generate the correct code.

Can you move the implementation into a source file?
Burnt_Fyr
Burnt_Fyr
Quote:
Original post by rip-off
You cannot call member functions of forward declared classes. The compiler must see the function declarations to preserve the type system and generate the correct code.

Can you move the implementation into a source file?


???

All member functions are implemented in their respective .cpp files, is this what you meant? If not please explain...
SiCrane
SiCrane
Then why is your error message listing the header as the location of the error?
Burnt_Fyr
Burnt_Fyr
@SiCrane: Typo...

b.cpp(xxx) : error 2027: use of undefined type 'c'    b.h(xxx) : see declaration of 'c'b.cpp(xxx) : error C2228: left of '.c_member_property' must have class/struct/union


@DimitriA: I apologize, your link I believe is the solution after all...

Each class, a,b,and c contain unnamed unions, which I now believe to be the cause of all my frustration... suggestions still welcome.
ThrustGoblin
ThrustGoblin
Sounds like you haven't included c.h in b.cpp.
Burnt_Fyr
Burnt_Fyr
Thanks for the help all... consider it solved issue was that class C had a member which was a union with a struct containing class A. Not an issue until C was needed in B.

class Plane { // formerly class C    union {      struct {          Vector3 norm; // formerly class A !!DOH!!         Real    dist;       };       struct {          Real a,b,c,d;      };};I should have caught this sooner, but lack of sleep/coffee had my head banging against the wall.
Burnt_Fyr
Burnt_Fyr
Well... What I had thought was solved, was not, but is now!

The issue was the inclusion of needed headers in the .h files. ThrustGoblin's post nailed it on the head. moving the #include directives into the .cpp files was the fix i wanted. I'm surprised that this is the first I've ran into it, but this was the first case of 3 interdependent classes I've come across. Up until now I had always used #include in the .h files, which was fine(with forward declarations) for 2 interdependent classes, but with 3 the compiler could never build a concrete definition of the classes. I see the folly of my ways, and would like to thank all again for the help, and allowing me to better understand the c++ language.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.