#ifndef not working

Started by
23 comments, last by Hawkblood 10 years ago


so I made a "main.h" and placed all those variables and function definitions in that.

Hopefully you meant "declarations." Don't put the definitions in a header!

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Advertisement

I tried that. I got lots of errors.

Please post the revised code, and the error messages. I have not tried to compile your code, but something like that should work. For example, I didn't include the header guards in globals.h, you'll still need them. And as mentioned, if you're declaring a global instance of Graphics, you'll need to include graphics.h in globals.h.

I'd second Buckeye's suggestion to remove all references to your functions and headers from stdafx.h. Unless you really know what you're doing, it is probably best to reserve stdafx.h for referencing external headers (like Windows.h) that really are used everywhere. In fact, it might be best to leave stdafx.h empty for the time being until you've figured out this problem first.


I'd second Buckeye's suggestion to remove all references to your functions and headers from stdafx.h. Unless you really know what you're doing, it is probably best to reserve stdafx.h for referencing external headers (like Windows.h) that really are used everywhere. In fact, it might be best to leave stdafx.h empty for the time being until you've figured out this problem first.

The problem with doing that is I have dependencies that require a certain order of "inclusion". I can't depend on the compiler to look through the header files in the right order.


Please post the revised code

I have a lot of code to look at now. I could post it if you think it will help, but here is the gist of what I have done:

--I have a header file for each .cpp file

--Each header file is "#included" is the stdafx.h file (in the order I need them)

--Each header file has:

#ifndef (header name in all caps such as GLOBALS_H)

#define (header name in all caps such as GLOBALS_H)

..... all the stuff needed in the header file.......

#endif

--Each .cpp file "#includes" the stdafx.h file

--stdafx.h has the same #ifndef / #define / #endif stuff as all the other headers

Here is the errors I'm getting when I do this:


Error	1	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\Grapgics.obj	Empty DX11 Project1
Error	2	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\Grapgics.obj	Empty DX11 Project1
Error	3	error LNK2005: "struct GRAPHICS Graphics" (?Graphics@@3UGRAPHICS@@A) already defined in globals.obj	C:\Empty DX11 Project1\Grapgics.obj	Empty DX11 Project1
Error	4	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\LargeMath.obj	Empty DX11 Project1
Error	5	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\LargeMath.obj	Empty DX11 Project1
Error	6	error LNK2005: "struct GRAPHICS Graphics" (?Graphics@@3UGRAPHICS@@A) already defined in globals.obj	C:\Empty DX11 Project1\LargeMath.obj	Empty DX11 Project1
Error	7	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	8	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	9	error LNK2005: "struct GRAPHICS Graphics" (?Graphics@@3UGRAPHICS@@A) already defined in globals.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	10	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\MeshObject.obj	Empty DX11 Project1
Error	11	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\MeshObject.obj	Empty DX11 Project1
Error	12	error LNK2005: "struct GRAPHICS Graphics" (?Graphics@@3UGRAPHICS@@A) already defined in globals.obj	C:\Empty DX11 Project1\MeshObject.obj	Empty DX11 Project1
Error	13	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\Text.obj	Empty DX11 Project1
Error	14	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\Text.obj	Empty DX11 Project1
Error	15	error LNK2005: "struct GRAPHICS Graphics" (?Graphics@@3UGRAPHICS@@A) already defined in globals.obj	C:\Empty DX11 Project1\Text.obj	Empty DX11 Project1
Error	16	error LNK1169: one or more multiply defined symbols found	C:\Empty DX11 Project1\Release\DX11Test.exe	1	1	Empty DX11 Project1
	17	IntelliSense: command-line error: invalid macro definition: /MDd	c:\Empty DX11 Project1\Text.cpp	1	1	Empty DX11 Project1

The /MDd error only shows up when the other errors do. When I change it to the way I *was* doing it, that error doesn't occur.....

From the errors you listed, it appears you're still defining (not declaring but defining) globals in header files. Either that, or you're defining the same global in more than one cpp file.

That is, it appears that some header file has something like:


float SCREEN_WIDTH; // not in a header file!

instead of


extern float SCREEN_WIDTH;

Check for that problem, and also ensure that float SCREEN_WIDTH; appears in only one cpp file.


Each header file is "#included" is the stdafx.h file (in the order I need them)

Two things:

First: if header files other than system-related files (sdkver, windows, etc.) have to be in a particular order, that's an indication of a potential problem. Can you describe why the order of header files makes a difference?

Second: As mentioned, stdafx.h should be reserved for information that all (or most) cpp files need - things like windows.x, etc. Including all project header files in stdafx.h isn't recommended. Cpp files should have include only those header files that are needed.

You may not want to try it at this point, but the #ifndef HEADER/#define HEADER/#endif can be replaced with a single #pragma once at the very top of the file.

EDIT: with regard to structs: [EDIT: deleted some incorrect terminology about structs - apologies]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I need some variables as global variables so that they may be used in multiple .cpp files. Exactly how should I do this? Should I use:

extern float WhateverVariable;

in a header file?
I'd recommend starting simple, you've a lot going on in your current program, so it is difficult to diagnose what is happening. Can you create a new project to try a simpler program - two source files and a header.

The following should work:

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

extern float SCREEN_WIDTH;
extern float SCREEN_HEIGHT;

#endif

globals.cpp:

#include "globals.h"

float SCREEN_WIDTH = 13.0f;
float SCREEN_HEIGHT = 42.0f;

main.cpp:

#include "globals.h"
#include <iostream>

int main() {
	std::cout << "Screen: " << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << std::endl;
}

You can either disable pre-compiled headers, or just include an empty one for the time being until you have a successful build.

That gives me:


Error	1	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	2	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in globals.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	3	error LNK1169: one or more multiply defined symbols found	C:\Empty DX11 Project1\Release\DX11Test.exe	Empty DX11 Project1

I tried playing with PCH, but all I got were errors.

The main thing is that I want to have *some* global variables. These would be common-use variables like the graphics interface. I want to do this so I don't have to send a reference each time some part of the program needs a pointer to the device......

GOT IT!

in stdafx.h I (extern) declare:

extern GRAPHICS *GE;//my graphics interface pointer

and in main.h I actually declare it:

GRAPHICS *GE;

this gives me "global" availability of the variable.................

GOT IT!

in stdafx.h I (extern) declare:

extern GRAPHICS *GE;//my graphics interface pointer

and in main.h I actually declare it:

GRAPHICS *GE;

this gives me "global" availability of the variable.................

Actually, you don't got it. sad.png

First: GRAPHICS *GE both declares GE AND defines it.

Read this --> Don't define variables in header files. If you must have a global variable, define it in a CPP file.

Also, if you're going to define a global variable, it's good practice to initialize it. I.e., GRAPHICS *GE = NULL;


I WANT TO CORRECT THIS!


Just trying to help out, Hawkblood. You posted this thread, looking to solve a problem, but you're ignoring the solution.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Works for me:


user@host:~/help$ for file in globals.{h,cpp} main.cpp; do echo "${file}:"; cat $file; done
globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
 
extern float SCREEN_WIDTH;
extern float SCREEN_HEIGHT;
 
#endif
 
globals.cpp:
#include "globals.h"
 
float SCREEN_WIDTH = 13.0f;
float SCREEN_HEIGHT = 42.0f;
main.cpp:
#include "globals.h"
#include <iostream>
 
int main() {
std::cout << "Screen: " << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << std::endl;
}
user@host:~/help$ g++ main.cpp globals.cpp -o help
user@host:~/help$ ./help
Screen: 13x42
 


GOT IT!

...

and in main.h I actually declare it:

GRAPHICS *GE;

This will appear to work fine if main.h is only #included into a single source file (i.e. main.cpp). Remember #include is glorified copy and paste - the compiler will see a file that ends with the contents of main.cpp with the contents of every included file at the top (assuming the convention where #include occurs at the top of the file).

If another source file #includes main.h, this will stop "working".

This topic is closed to new replies.

Advertisement