Jump to content

  • Log In with Google      Sign In   
  • Create Account


c++ help me organize my includes correctly


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
32 replies to this topic

#21 breakspirit   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 October 2011 - 08:05 PM

Thanks for the input guys. I created the .cpp files and am still getting the same errors with the addition of the fact that gamesimulation has mysteriously forgotten about Variables.h. When I manually included it in gamesimulation.h, I got different errors. So, I included the current code and here's the errors:
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\netcode.cpp(101): error C2027: use of undefined type 'GameSimulation'
1>      	c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\netcode.h(21) : see declaration of 'GameSimulation'
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\netcode.cpp(101): error C2228: left of '.addNewPlayer' must have class/struct/union
1>  GameSimulation.cpp
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.h(17): error C2065: 'GAME_WIDTH' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.h(17): error C2065: 'GAME_HEIGHT' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.h(19): error C2143: syntax error : missing ';' before '<'
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.h(19): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.h(19): error C2238: unexpected token(s) preceding ';'
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(7): error C2065: 'GAME_WIDTH' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(10): error C2065: 'GAME_HEIGHT' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(12): error C2065: 'GAME_HEIGHT' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(15): error C2065: 'GAME_WIDTH' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(21): error C2065: 'playerList' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(21): error C2228: left of '.push_back' must have class/struct/union
1>      	type is ''unknown-type''
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(22): error C2065: 'playerList' : undeclared identifier
1>c:\users\kev\desktop\game stuff\raknet stuff\raknettest\raknettest\gamesimulation.cpp(29): error C2065: 'isServer' : undeclared identifier

Attached Files

  • Attached File  blah.zip   5.72KB   16 downloads


Sponsor:

#22 SiCrane   Moderators   -  Reputation: 9495

Like
0Likes
Like

Posted 07 October 2011 - 08:13 PM

If you actually want to use a class type, you can't get by with just a forward declaration, you need the full definition. So #include the relevant header file when you use the variable. Just to make things clear: just because one of your source file includes a header doesn't mean that every other file will see the contents. Every file that needs the contents of the header needs to include that header.

#23 pulpfist   Members   -  Reputation: 528

Like
0Likes
Like

Posted 07 October 2011 - 08:22 PM

See my reply #4

#24 yckx   Prime Members   -  Reputation: 1163

Like
0Likes
Like

Posted 07 October 2011 - 08:24 PM

You forward declare GameSimulation in NetCode.h, but you still need to include GameSimulation.h in NetCode.cpp in order to use its methods. GameSimulation.h doesn't know about GAME_WIDTH or GAME_HEIGHT because the include line for Variables.h is commented out. Use std::vector instead of vector on line 19 of GameSimulation.h. isServer, used in GameSimulation::setUpNewPlayer(), is not available because the include line for Variables.h is commented out in GameSimulation.h.

#25 breakspirit   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 October 2011 - 08:30 PM

I'm down to just the errors with gamesimulation.h and cpp not being able to see the contents of Variables.h. If I uncomment out #include "Variables.h" I get different errors, as shown below:

1>main.obj : error LNK2005: "bool isServer" (?isServer@@3_NA) already defined in GameSimulation.obj
1>main.obj : error LNK2005: "void * hStdout" (?hStdout@@3PAXA) already defined in GameSimulation.obj
1>main.obj : error LNK2005: "unsigned __int64 startTime" (?startTime@@3_KA) already defined in GameSimulation.obj
1>NetCode.obj : error LNK2005: "bool isServer" (?isServer@@3_NA) already defined in GameSimulation.obj
1>NetCode.obj : error LNK2005: "void * hStdout" (?hStdout@@3PAXA) already defined in GameSimulation.obj
1>NetCode.obj : error LNK2005: "unsigned __int64 startTime" (?startTime@@3_KA) already defined in GameSimulation.obj
1>C:\Users\Kev\Desktop\Game stuff\Raknet stuff\RakNetTest\Debug\RakNetTest.exe : fatal error LNK1169: one or more multiply defined symbols found

That makes me think that I'm including Variables.h too many times somewhere. Player.h is not including Variables currently and when it does, I get more errors of the same sort.

#26 SiCrane   Moderators   -  Reputation: 9495

Like
0Likes
Like

Posted 07 October 2011 - 08:32 PM

Dude, seriously, read the article I linked. Duplicate symbols is problem 4. You need extern declarations for globals in headers.

#27 breakspirit   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 October 2011 - 08:43 PM

Dude, seriously, read the article I linked. Duplicate symbols is problem 4. You need extern declarations for globals in headers.


by that, you mean doing the following in gamesimulation.h, right?
extern const int GAME_WIDTH;
extern const int GAME_HEIGHT;

and the like with the rest of the globals? That's what I've been doing and it's not working for me. I did read the article you linked, twice now, and I feel like I'm just overlooking something.

edit: It's just not working with the line
char gameWorld[GAME_WIDTH][GAME_HEIGHT];
presumably because it needs to know the exact values of these globals. It did correctly get it to shut up about isServer.

#28 pulpfist   Members   -  Reputation: 528

Like
0Likes
Like

Posted 07 October 2011 - 09:01 PM


Dude, seriously, read the article I linked. Duplicate symbols is problem 4. You need extern declarations for globals in headers.


by that, you mean doing the following in gamesimulation.h, right?
extern const int GAME_WIDTH;
extern const int GAME_HEIGHT;

and the like with the rest of the globals? That's what I've been doing and it's not working for me. I did read the article you linked, twice now, and I feel like I'm just overlooking something.

edit: It's just not working with the line
char gameWorld[GAME_WIDTH][GAME_HEIGHT];
presumably because it needs to know the exact values of these globals. It did correctly get it to shut up about isServer.


No, well kindof but thats not enough.

First, the global variables in Variables.h needs to be placed in a cpp file.
One way to do it could be to create a Variables.cpp and move them there:

Variables.cpp

bool			isServer;
HANDLE			hStdout					= GetStdHandle(STD_OUTPUT_HANDLE);	// Used to clear the screen or change text properties
RakNet::Time	startTime				= RakNet::GetTimeMS();
const int		GAME_WIDTH				= 30;
const int		GAME_HEIGHT				= 15;

Variables.h

extern bool			isServer;
extern HANDLE			hStdout;
extern RakNet::Time	startTime;
extern const int		GAME_WIDTH;
extern const int		GAME_HEIGHT;

Now, if you have a file that needs access to any of these global variables, include Variables.h


The link you got from Sicrane probably explains this better than me, but basically the problem you have here is similar to the problem you had earlier when you moved some functions from header files into cpp files.

An expression like this

bool isServer;


is both a declaration and a definition!
Since we don't want to have definitions in header files, we move those variables into a cpp file and leave behind only the extern versions in the header, which is only a declaration.


Think about that for a moment Posted Image

#29 breakspirit   Members   -  Reputation: 100

Like
0Likes
Like

Posted 11 October 2011 - 11:54 AM

Thanks again for the help guys. I just want to update this thread for anyone who reads through it. I did resolve all my issues by the suggested methods except my array in gamesimulation still kept whining about the global constants used to size it. I ended up simply using #define GAME_WIDTH 30 instead of using a const and that instantly solved my issues. The global variables and constants I'm still using are correctly working with the extern command. Now to finally proceed with writing the fun stuff.
Again, thanks for the help.

#30 way2lazy2care   Members   -  Reputation: 782

Like
1Likes
Like

Posted 11 October 2011 - 01:18 PM

I think you should use either

#ifndef ?
#define ?
...
#endif

or

#pragma once

but not both,

Why not both? I use both all the time. GCC at one point didn't have good support for it, but now I believe having #pragma once and #ifndef checks gives you the best of both worlds for the vast majority of situations. More than likely unless you already know it will break your project having both, you will probably be fine using both.

#31 Wooh   Members   -  Reputation: 592

Like
0Likes
Like

Posted 11 October 2011 - 02:18 PM


I think you should use either

#ifndef ?
#define ?
...
#endif

or

#pragma once

but not both,

Why not both? I use both all the time. GCC at one point didn't have good support for it, but now I believe having #pragma once and #ifndef checks gives you the best of both worlds for the vast majority of situations. More than likely unless you already know it will break your project having both, you will probably be fine using both.

I don't think there is a problem in using both but why use both when they do the same thing?

#32 SiCrane   Moderators   -  Reputation: 9495

Like
1Likes
Like

Posted 11 October 2011 - 03:01 PM

The usual explanation is that you get the performance benefit if the preprocessor supports pragma once, but it remains backwards compatible with tool chains that don't.

#33 achild   Crossbones+   -  Reputation: 1619

Like
1Likes
Like

Posted 11 October 2011 - 03:14 PM

Just thought I'd chime in it is perfectly safe to declare a constant variable in a header. But you have to assign it something. No need for extern.


const unsigned int SOME_CONST = 23;


is perfectly okay in a header file, even if you include it a zillion times. The problem I saw above was the a constant variable was declared, but it wasn't assigned a value at the same place. Ie you were doing this:


const unsigned int SOME_CONST; // no good - how are you going to assign it now?

That would fix your problems with the const, assuming you have the appropriate inclusion guards. No need to use #define for the consts. As you noticed, using extern on the const globals created other problems when defining creating arrays because you had no way to know what the constant value actually is yet. No need to use extern for constant globals, just constant variables.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS