# missing storage-class or type specifiers

This topic is 4613 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I get these errors:
d:\Documents\CPP\Visual Studio Projects\TileSystem\Game.h(30) : error C2143: syntax error : missing ';' before '*'
d:\Documents\CPP\Visual Studio Projects\TileSystem\Game.h(30) : error C2501: 'Game::Console' : missing storage-class or type specifiers
d:\Documents\CPP\Visual Studio Projects\TileSystem\Game.h(30) : error C2501: 'Game::Console' : missing storage-class or type specifiers


On this line: Console* Console; // for the console Im trying to do a console and for some reason it seems not to recognice my console class. Console.h is included and the class is defined there, if it wasnt it should state other errors to, shouldnt it? What could be wrong?

##### Share on other sites
Console * console;

##### Share on other sites
Console * Console; == Console* Console;

Right?

##### Share on other sites
"Console * console" != "Console * console" (case matters).

##### Share on other sites
I changed the line to this but I still gets the exact same errors... you sure thats whats wrong?

Console * console; // for the console

##### Share on other sites
Console * Console;

Is fine in C++, as is

Console *Console;

And

Console* Console;

The only problem with doing this is that it hides the Console class for the rest of the scope in which the Console variable is defined. For example

class Console{...};int main(){  Console * Console;  Console * Console2;}

Here the Console * Console2; line will give you an error, as it thinks Console is now a variable of type pointer, and interprets Console * Console2; as a multiplication, since Console2 has not been previously defined, you get an error.

There is a way around this, you can qualify the second Console definition with the class keyword, that will tell the compiler that Console refers to a class, and not a variable of type pointer.

class Console{...};int main(){Console * Console;class Console * Console2;}

This now compiles. This is an example of using an 'elaborated type specifier'. You will need to post more code describing the problem.

##### Share on other sites
Yup, thanks, that solved it. But on the line above I have

FontSystem* Font; // for printing text on the screen

Which works fine, why not the console? I couldnt find anywhere in the project where I did make another Console class as you showed there.

##### Share on other sites
Quote:
 Original post by MizipzorYup, thanks, that solved it. But on the line above I haveFontSystem* Font; // for printing text on the screenWhich works fine, why not the console? I couldnt find anywhere in the project where I did make another Console class as you showed there.

In this case it is likely that the elaborated type specifier simply declared the Console class as existing somewhere in the project. This suggests that you have not actually included the Console header file in the .cpp file that the line of code Console * Console exists in. It is worth you double checking.

##### Share on other sites
Console.h is included.

Game.h (as you can see, the console is at the top and I got other class pointers working fine)
#ifndef _GAME#define _GAME#include <SDL.h>#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <windows.h>#include "SdlHandle.h"#include "Player.h"#include "AsciiMap.h"#include "Log.h"#include "Defines.h"#include "FontSystem.h"#include "Console.h"class Game {protected:	// Singleton class	static Game* m_pInstance;	Game( void );private:	SdlHandle*	Sdl;			// for the graphics	Player		Player;			// the player	AsciiMap	AsciiMap;		// the tiles represented by chars	Log			Log;			// for the logs	FontSystem*	Font;			// for printing text on the screen	class Console*	Console;		// for the Console		bool		running;		// is the game running	Uint8*		keys;			// to keep track of the keys	SDL_Event	event;			// event tracker (keys)public:	// Singleton ---	static Game* GetInstance( void ) {		if ( !m_pInstance )			m_pInstance = new Game();		return m_pInstance;	};	// init stuff ---	bool	InitVideo();		// init graphics	// main stuff --- 	void	RenderWorld();		// draws all the tiles	void	MainLoop();			// the main loop	void	RawCommand(std::string Command);	// for recieving raw commands from the Console};#endif

##### Share on other sites
Its possible you could have some circular dependancy issues. Does the Console.h file include the Game.h header file too?

##### Share on other sites
Actually yes, the console class has an instance of the game class (commands from the console must be passed to the game class)

##### Share on other sites
That explains it then. [smile]

The problem lies in how the C++ inclusion system works. When you hit the compile button, the preprocessor takes over to replace the preprocessor keywords in every .cpp file with something the compiler will understand. What you end up with after the preprocessor has finished is something called a 'translation unit'.

One of the simplest jobs the preprocessor does is copying and pasting code for you, which is why header files are useful, it simply replaces the #include directive with the code that is inside the file that is specified, for example.

//console.hclass console{};//some.cpp#include"console.h"console instance;

Here the preprocessor would see the #include preproccessor symbol and replace it with the contents of the file specified, which is console.h. Leaving the some.cpp translation unit as.

//some.cpp translation unitclass console{};console instance;

Things get trickier when you add inclusion guards into the equation (which are used to prevent things from being defined multiple times within a translation unit). The standard states as part of its so called "One defintion rule", that you cannot have a class defined twice within a translation unit, so your compiler will give you are error if you do. So if you were to include the console.h file twice in some.cpp.

//console.hclass console{};//some.cpp#include"console.h"#include"console.h"console instance;

The subsequent generated translation unit would be.

//some.cpp translation unitclass console{};class console{};console instance;

As you can see, the some.cpp translation unit has the console class defined twice, which breaks the C++ standards One Definition Rule, and so issues a compiler error. This is why you need header guards, which are at the heart of your problem.

//console.h#ifndef _console#define _consoleclass console{};#endif//some.cpp#include"console.h"#include"console.h"console instance;

Here we can see header guards at work, again we have included the file twice, but the preprocessing symbols will prevent the console class from being included twice. How it does that depends on how the preprocessor is implemented, but it could simply have a table of names that have been defined with the #define directive. When it executes the first include directive, it reaches the first #ifndef and checks to see if it has _console in its table, it doesn't, so it carries on. When it reaches its second include directive, it again reaches an #ifndef _console, so it checks to see if _console has been defined in its table, it has, so it does not carry on, and the code is not included. This leaves us with a translation unit like

//some.cpp translation unitclass console{};console instance;

Now onto the topic in question, circular inclusions

//console.h#ifndef _console#define _console#include"game.h"class console{ game* pgame_;};#endif//game.h#ifndef _game#define _game#include"console.h"class game{ console* pconsole_;};#endif//some.cpp#include"game.h"console console;

Here we have introduced a circular inclusion, game.h includes console.h which includes game.h which includes console.h which... [smile]

The header guards have come to the rescue again though, and the preprocessor will not get stuck in an infinite loop. This is a slightly more involved proprocessor program, but uses the same simple rules as before.

First the preprocessor is executed on some.cpp, it sees the #include directive and so goes about copying the code from game.h into some.cpp.

It reaches the first #ifndef _game, it checks its table and sees it has not been defined yet, and so carries on.

It then reaches the #include"console.h" directive in game.h, and goes about copying that into some.cpp.

It reaches the first #ifndef _console directive, it checks its table and sees it has not been defined yet, and so carries on.

It then reaches the #include"game.h" directive in console.h, and goes about copying the game.h code into some.cpp

it reaches the #ifndef _game directive for the second time, checks its table and sees it is defined!

This stops the infinite loop, but leaves us with a slightly error prone translation unit looking like:

//some.cpp translation unitclass console{ game* pgame_;};class game{ console* pconsole_;};console console;

Now when the compiler is finally executed on this translation unit, it runs into a problem almost immedietly. It reaches the line game* pgame_; and asks itself what game is, is it a variable or a type? It has noway of knowing as the circular depedancy has meant that the game class has not yet been declared or defined (it is defined later in the translation unit as we can see).

The simple fix for this that we stumbled on is to use an elaborated type specifier to predeclare the type game, so the compiler knows what it is and can continue. This is done by simply prefixing game* pgame_; with the keyword class in this case. This would leave the translation unit as

//some.cpp translation unitclass console{ class game* pgame_;};class game{ console* pconsole_;};console console;

Now the compiler knows that game* is a type and not a variable, and so it can continue compiling. It is also worth doing the same to the console* pconsole_; line, as this would also give the same error if we had included the console.h file first in some.cpp instead of the game.h header file.

Congratulations to anyone who made it this far. [smile]

##### Share on other sites
Hehe I had to read that twice to understand :P but know I know why... also how a compiler works... hehe... thanks for taking the time to write that, two thumbs up and a rating for you. :)

##### Share on other sites
You can also solve the problem with a forward declaration, i.e. arranging such that the translation unit looks like

class game;class console{ game* pgame_;};class game{ console* pconsole_;};console c;