# Confused as to why this wont compile

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

## Recommended Posts

Hi Guys,

I am scratching my head at the moment with this one.

I have a class which I have stripped right back to bare bones trying to work out why it wont compile in my app.

 #pragma once class Asset { public: Asset() { ++(this->nID); // Asset ID (auto-increments) } ~Asset() { } private: static int nID; }; int Asset::nID=0; 

When I compile in my main application I get the following error;

"private: static int Asset::nID" ([email="?nID@Asset@@0HA"]?nID@Asset@@0HA[/email]) already defined in framework.obj

I have taken the above and put it into a brand new C++ project and it compiles fine.

I cant understand why it wont compile in the 'primary' application I am working with.

Even if I change the nID variable to something else, then the new variable name is 'already defined'. So, it isn't a variable redefinition problem.

Any ideas on this would by hugely appreciated.

##### Share on other sites
Posted · Hidden
Hidden
Hi Guys,

I am scratching my head at the moment with this one.

I have a class which I have stripped right back to bare bones trying to work out why it wont compile in my app.

 #pragma once class Asset { public: Asset() { ++(this->nID); // Asset ID (auto-increments) } ~Asset() { } private: static int nID; }; int Asset::nID=0; 

When I compile in my main application I get the following error;

"private: static int Asset::nID" ([email="?nID@Asset@@0HA"]?nID@Asset@@0HA[/email]) already defined in framework.obj

I have taken the above and put it into a brand new C++ project and it compiles fine.

I cant understand why it wont compile in the 'primary' application I am working with.

Even if I change the nID variable to something else, then the new variable name is 'already defined'. So, it isn't a variable redefinition problem.

Any ideas on this would by hugely appreciated.

try setting the value inside the class or something

##### Share on other sites
"int Asset::nID=0;" is defining the variable.
So put it into a .cpp file rather than header.

##### Share on other sites
Put the
int Asset::nID=0;

##### Share on other sites
Don't know if that's the whole header file you posted here but, in case it is, it's best practice to wrap the code in a header with "#ifndef" directives.

example: name_of_file.h
 #ifndef NAME_OF_FILE_HEADER #define NAME_OF_FILE_HEADER //Put your code here... #endif 

If you don't do this you may have conflict issues when compiling.

Good luck! Edited by TMarques

##### Share on other sites
Source code (a.cpp, x.h) --(preprocessor)--> compilation_unit ---(compiler)--> a.o/.obj Source code (b.cpp, x.h) --(preprocessor)--> compilation_unit ---(compiler)--> b.o/.obj --(linker)--> executable Source code (c.cpp, x.h) --(preprocessor)--> compilation_unit ---(compiler)--> c.o/.obj

cpp file #includes header (.h) files. Compiler then converts stuff in those into code and symbols. nAssets is a symbol. At that point it's just a reference to something unknown, compiler doesn't care about it beyond a name.

Since each cpp is processed independently, we end up with 3 object files, each containing their own copy of nAssets. When linker puts all 3 together, it has 3 copies of nAssets.

By putting nAssets into .cpp file, such as (a.cpp), it will only generate one symbol, avoiding the confusion.

Header guard (pragma once) only prevents inclusion into same compilation unit. If x.h is included multiple times when preprocessing a.cpp, it will only appear the first time. But it will be included fully again when preprocessing b.cpp and c.cpp.

int Asset::nID=0;[/quote]This line actually says: "reserve 4 bytes inside executable at precisely this location. When someone needs nAssets symbol, give them this pointer".

Unlike most other languages, it's more than just semantic annotation, it's fairly important choice on where to put it.

it's best practice to wrap the code in a header with "#ifndef" directives.[/quote]

It is, but pragma once is fairly well supported these days and does the same. I prefer header guards myself. Edited by Antheus

##### Share on other sites
Putting the variable into a CPP file did the job.

I still don't understand why a straight cut and paste of the same code into a new project worked ok, though. Must be one of those strange compiler things.

Thanks guys, I was starting to tear my hair out.

##### Share on other sites

I still don't understand why a straight cut and paste of the same code into a new project worked ok, though. Must be one of those strange compiler things.

Definition in header will work as long as the header is included in only one CPP.
That's to say, the definition is in only one translate unit.
If the header is included in more than one CPPs, it won't link due to duplicated definition. Edited by wqking

##### Share on other sites

I still don't understand why a straight cut and paste of the same code into a new project worked ok, though. Must be one of those strange compiler things.

Because your new project probably either a) only includes the header once or b) you copied the class into a cpp file.

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 10
• 23
• 9
• 32
• ### Forum Statistics

• Total Topics
632631
• Total Posts
3007532
• ### Who's Online (See full list)

There are no registered users currently online

×