Jump to content


Why it doesn't see the token?


7 replies to this topic

#1 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 326 posts

Posted 24 October 2007 - 03:42 PM

Hello,
yesterday I broke my project. Wouldn't compile anymore.
It's a big project started time ago and consists of many translation units.

Over time I have applied quick changes, fixes, substituted old versions of objects with new ones...
Short story: I had a messy chain of dependancies, with multiple class forwardings, repetition of typedefs, and such.

So yesterday the problem gets serious: can't go any further if I don't clean the mess.
I do it.
Now the inclusions are more straightforward, and the whole is so much cleaner.
But 1 symbol is not recognized.

Error C2143: syntax error: ';' missing before '*'
It's a classic.

The weird thing is that the missing symbol is not missing.
Instead it's fully defined in the header (ClassA.h) that's being included immediately before the one header (ClassB.h) into which the error bumps.

Here is a better explanation of the situation:
(NOTE: There are include guards in each header)

//------------------------------------------------------------

FILE: Master.h


#include "Types.h"

#include "ClassA.h"

#include "ClassB.h"



//------------------------------------------------------------

FILE: Types.h


... // No includes. This header houses simple UDTs, typedefs, and

    // other stuff that is independant of other translation units.

    // Touching Types.h triggers a full rebuild (ouch!)



//------------------------------------------------------------

FILE: ClassA.h


#include "Master.h"


class ClassA

{

    // full definition of ClassA

};



//------------------------------------------------------------

FILE: ClassB.h


#include "Master.h"


class ClassB

{

    ClassA* pA; // at this point 'ClassA' token is not defined

};


After seeing the error, I have quit the IDE.
I have deleted the Debug builds and all .ncb files, just to be sure.
Then I recompiled from scratch.
ClassA.cpp gets compiled before ClassB.cpp, as expected. Yet the error persists.

The solution is to forward "class ClassA;" inside ClassB.h. I understand why.
Instead I don't get why it doesn't 'see' the full definition of ClassA.

Anyone can tell me?

Regards,
Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#2 J22

    Member

  • Members
  • PipPip
  • 92 posts

Posted 24 October 2007 - 07:06 PM

Because there is circular dependency in header file inclusion.

#3 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 24 October 2007 - 08:44 PM

Let's carefully track the sequence of inclusions here.

Suppose your .cpp file includes ClassA.h. That will include Master.h, which includes Types.h and then ClassA.h. Since the include guard for ClassA.h is already in place, this inclusion of ClassA.h will be skipped. However, at this point ClassA has not been defined, since we are still processing the '#include Master.h' from ClassA.h! Then ClassB.h will be included (from Master.h), and will give an error since ClassA hasn't yet been defined.

The solution is to only include those things in ClassA.h that it actually needs. Instead of including Master.h, just include Types.h (assuming ClassA is dependent on those type definitions). Similiarly, in ClassB.h, rather than including Master.h just include ClassA.h and whatever other headers are specifically needed by ClassB.
reedbeta.com - developer blog, OpenGL demos, and other projects

#4 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 326 posts

Posted 24 October 2007 - 10:12 PM

That's perverse... did I do that? :p yuk!
I've been lazy. Lesson learned.

Thanks for your time,
Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#5 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 25 October 2007 - 09:20 AM

As the ClassA in ClassB is a pointer and hence the compiler doesn't need to know its definition (just that it exists) its better to, simply, add a forward declaration for ClassA before ClassB ... done like so


class ClassA;


Job done :) Better than including headers from headers. You want to try and avoid doing that as much as possible as it badly impacts compilation time. A #include is nothing more than a compiler driven cut and paste into whatever CPP file is being generated. Go through each #include in your CPP file and imagine cutting and pasting the contents of the header in place of that #include. For each #include in the header do the same and you'll quickly see why avoiding #includes whenever possible is a good plan :)

#6 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 326 posts

Posted 25 October 2007 - 02:08 PM

I understand.
As I said: I've been lazy.
After touching nearly every unit in the project (took a while), I badly wanted to see if it'd work.
Having 22 headers around, I didn't feel like setting up a specific #include list for each .cpp...

And some classes need to know about each other anyway... at some point I end up with circular dependency again.
It's the first project of mine to become so complex. Thought I had enough experience under the belt to avoid these problems.

Hats off to the professionals! They engineer systems from the ground up and make 'em work together as if it's the easiest thing in the world, while *I* am already fighting with something that reaches (perhaps) 1/10th the complexity of their work.

Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#7 z80

    Valued Member

  • Members
  • PipPipPip
  • 104 posts

Posted 25 October 2007 - 07:08 PM

That is what coding is all about isnt it? The endless battle against complexity..

#8 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 26 October 2007 - 08:36 PM

Nautilus said:

Hats off to the professionals! They engineer systems from the ground up and make 'em work together as if it's the easiest thing in the world

:lol:

If only it were easy ... It gets much much harder when you have colleagues. Every programmer believes they know the best possible way to do things. Thats why all games run late. I once worked with a manager who took no shit. Everything people did had to be done right and if it was done wrong they'd have to redo it till it was right (After a couple of times people did it right from the word go). His project was a month ahead of schedule (On an 11 month full game schedule which is hellishly quick) ... he was one of those professionals you speak of. There aren't many of them out there. Wish i was one! The worst thing is ... That project got canned and the publisher defaulted on the payments ... at alpha :(

You got a good attitude, though. Keep going .. you'll learn and you'll find it gets a HELL of a lot easier with experience :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users