Page 1 of 2

C++ oddness and I need some insight/help.

Posted: Wed Jul 22, 2009 4:33 am
by Dark Alchemist
I have moved some static functions into their own .cpp and .h files and if I #include the .cpp (it #includes the .h) it compiles in GCC and MSVC just fine but if I bring them into the project they upchuck with really weird errors (i.e. OpenThread has not been defined and Function XX has been declared but not defined). What am I doing wrong? I can't figure out why something would work outside of the project but not if I include it (with the #include statements or not it doesn't matter).

Posted: Wed Jul 22, 2009 6:44 am
by Jorg
if I #include the .cpp (it #includes the .h)
You should always include .h files. The reason is that if you include cpp files, it will statically compile the file inside the other file making it still invisible for the referencing cpp files. Always do;

.hpp

Code: Select all

#ifndef __SOME_UNIQUE_NAME__
#define __SOME_UNIQUE_NAME__

// add your declarative code here
// only use inline code (like getters/setters)

#endif
.cpp

Code: Select all

#include "yourfile.h"

// put your implementation here

In other files that need to reference;

Code: Select all

#include "yourfile.h"

// code for the other module.
Stick to this and I am sure your problems will go away... Also, 1) if you only use foreign classes inside the implementation cpp file, only include the .h file in that file. 2) If you declare foreign classes as members or arguments then only put it in your .h file which gets included anyway.

With regards,
- Jorgen

Posted: Wed Jul 22, 2009 7:47 am
by Dark Alchemist
Well, I do all of that as it is but what has me stumped is that if, while doing the above, I bring them in to the project (so they are in the list of files) I can't compile them but if I leave them out (without doing anything else) the project compiles.

See my project is getting too huge to manage without breaking it up into sections and doing that seems to be a major headache for some reason.

What is really aggravating is that I did like you said and I get 37 errors of already defined in somefile.obj but when I look I see no dupes and with my ifndef endif I should only get it one time so why the already defined at the link stage? I read MSDN and none of it applied that I could see.

Posted: Wed Jul 22, 2009 8:52 am
by Jorg
Hi, maybe post a few excerpts of the file you are having problems with, the header, the specific section and the footer? Also it might help to see some of the errors you are getting.

With regards,
- Jorgen

Posted: Wed Jul 22, 2009 12:55 pm
by Dark Alchemist
Well, you would have to see the entire project as just seeing the header file isn't going to help much. The thing is GCC has completely different errors (I think really invalid and esoteric) versus MSVC.

I guess I will just have to live with #include the cpp and remove it from the project files list as that solves my issues 100% it just sucks if I need to touch the file again.

Thanks for the help but, as I said, you would need to have the entire project for this as just looking at the header file, even if you saw all of it, would not help with a "already defined in somefile.obj" type error.

Posted: Wed Jul 22, 2009 2:15 pm
by DavidHart
What is really aggravating is that I did like you said and I get 37 errors of already defined in somefile.obj but when I look I see no dupes and with my ifndef endif I should only get it one time
What's likely to be happening is you #include your .cpp file in more than one project file.

e.g. the file you #include is foo.cpp, and you need this both in bar.cpp and in baz.cpp. That means the linker sees it twice, and it doesn't like that. Protecting with:
#ifndef __SOME_UNIQUE_NAME__
#define __SOME_UNIQUE_NAME__
doesn't help here: as far as baz.cpp is concerned, __SOME_UNIQUE_NAME__ is undefined, even though bar.cpp knows about it.

You can declare something as often as you like, but you can only define it once. That's why you should put all your declarations in header files, which you can #include wherever you like; and the definitions in .cpp files, which you make part of the project. You can #include a cpp file if it's really necessary, but only once.

Regards,

David

Posted: Wed Jul 22, 2009 9:33 pm
by Dark Alchemist
The problem is I am doing the opposite of that. I do not #include the .cpp and only #include the .h in two files as the declarations (int X, etc...) are in that header file that both files need. The header file has the include guard in it but if I drop the #include .cpp and just #include the .h I can't compile it. Now if I drop the .h and include the .cpp it works but the .cpp nor the .h can be in the project.

This doesn't make any sense whatsoever.

So, I was reading and I tried to /force:multiple and it worked only crashed me when I tried to exit the program but the thing is that in that copy there is only a #include of the header file no .cpp is being included.

Damn annoying and hard to figure out what is going on behind the scenes to cause this.

Now, for something really odd MSVC complains that I have multiple defines (2 actually of each of the 37) while GCC says a few of my symbols aren't declared which is opposite of the error that MSVC is complaining about.

Let me give an example.

Code: Select all

"int lpAddress2" ([email protected]@3HA) already defined in Collector.obj
Now I ctrl-shift-f (find in all files) lpAddress2 and what do I see? This

Code: Select all

  C:\Dev-Cpp\My Projects\Collector.h(72):int     lpAddress1, lpAddress2, lpAddress3, lpAddress4;
  C:\Dev-Cpp\My Projects\Collector.cpp(62):    lpAddress2 = 0x420000;
All of the errors are exactly like this one so why is my question?

Posted: Thu Jul 23, 2009 1:16 am
by Auria
Let's come back to basics :

1) Never include a .cpp file (unless you want to do some pretty advanced stuff and know precisely what you're doing, but even then it's poor style), so please stop trying including .cpp files
2) You said you get an error when not including the C++ file. Please post this error (the exact text, not your interpretation of it) along with the relevant bits of code.

Posted: Thu Jul 23, 2009 1:55 am
by Dark Alchemist
Auria wrote:Let's come back to basics :

2) You said you get an error when not including the C++ file. Please post this error (the exact text, not your interpretation of it) along with the relevant bits of code.
I just did in the above response. The exact error number is (and MSDN solution of this issue none of their help pertained to my situation)

Code: Select all

"error LNK2005: "int lpAddress2" ([email protected]@3HA) already defined in Collector.obj"

Posted: Thu Jul 23, 2009 5:56 am
by tan
Hi,
Dark Alchemist wrote: Let me give an example.

Code: Select all

"int lpAddress2" ([email protected]@3HA) already defined in Collector.obj
Now I ctrl-shift-f (find in all files) lpAddress2 and what do I see? This

Code: Select all

  C:\Dev-Cpp\My Projects\Collector.h(72):int     lpAddress1, lpAddress2, lpAddress3, lpAddress4;
  C:\Dev-Cpp\My Projects\Collector.cpp(62):    lpAddress2 = 0x420000;
All of the errors are exactly like this one so why is my question?
it is quite clear error messages. Declare lpAddress2 in the Collector.h as extern.

Collector.h

Code: Select all

extern int lpAddress2, ...
Collector.cpp

Code: Select all

int lpAddress2=...

Posted: Thu Jul 23, 2009 6:21 am
by Dark Alchemist
So, everything in the .h needs to be extern? That seems rather odd as I have hardly ever used extern before so seeing an entire header file demanding it seems really strange to me.

I am about to give up as I did what you said and it compiled. I then rebooted and now everything that is extern says

Code: Select all

error LNK2001: unresolved external symbol "int lpAddress2" ([email protected]@3HA)
and if I remove the extern I am back to the previous error message. Maybe I am going to be forced into #include .cpp for this project afterall.

Posted: Thu Jul 23, 2009 9:43 am
by tan
Dark Alchemist wrote:So, everything in the .h needs to be extern?
No. It needs only if you declare a variable in .h file and include this h file in several .cpp files.
In this case compiler creates the instance variable per each cpp file. It in turn leads to the linker error ""int lpAddress2" ([email protected]@3HA) already defined in Collector.obj".
Dark Alchemist wrote: That seems rather odd as I have hardly ever used extern before so seeing an entire header file demanding it seems really strange to me.

I am about to give up as I did what you said and it compiled. I then rebooted and now everything that is extern says

Code: Select all

error LNK2001: unresolved external symbol "int lpAddress2" ([email protected]@3HA)
and if I remove the extern I am back to the previous error message.
If you declare a variable as extern in h file, you HAVE TO define it in one (and ONLY one) of cpp files. Otherwise you receive linker error "unresolved external symbol "int lpAddress2" ([email protected]@3HA)".

Posted: Thu Jul 23, 2009 12:38 pm
by Dark Alchemist
tan wrote:
Dark Alchemist wrote:So, everything in the .h needs to be extern?
No. It needs only if you declare a variable in .h file and include this h file in several .cpp files.
In this case compiler creates the instance variable per each cpp file. It in turn leads to the linker error ""int lpAddress2" ([email protected]@3HA) already defined in Collector.obj".
Dark Alchemist wrote: That seems rather odd as I have hardly ever used extern before so seeing an entire header file demanding it seems really strange to me.

I am about to give up as I did what you said and it compiled. I then rebooted and now everything that is extern says

Code: Select all

error LNK2001: unresolved external symbol "int lpAddress2" ([email protected]@3HA)
and if I remove the extern I am back to the previous error message.
If you declare a variable as extern in h file, you HAVE TO define it in one (and ONLY one) of cpp files. Otherwise you receive linker error "unresolved external symbol "int lpAddress2" ([email protected]@3HA)".
Now we are going around in circles because, as I said and showed earlier in the thread, all of these *are* declared and defined in only one file.

See this is why I am not understanding these errors because I know how to handle a cpp and a h file but for some darn reason this is not working. I do know this if I leave the .h with all of the definitions and pull the cpp into the main cpp (meaning the cpp is now gone as I have c&p'd it into the main cpp) all errors vanish.

I do thank everyone on this thread so don't get the wrong idea there I am just perplexed because I do know what goes in a header file and what is supposed to go into the cpp file yet, in this instance, everything is complaining. I have never had this issue before. To be frank I should be able to just cut any cpp file into as many pieces as I want, heck maybe even one function per cpp, and I should not be having these issues.

Posted: Thu Jul 23, 2009 12:44 pm
by phlox81
Don't use global variables.
Also static functions are only few times helpful.

Posted: Thu Jul 23, 2009 1:19 pm
by Dark Alchemist
phlox81 wrote:Don't use global variables.
Also static functions are only few times helpful.
Static must be used in windows for doing threads or at least that is everything I have read says.

As far as global goes it is because of the thread that must exist on its own (i.e. static). So, with a thread that is existing in the global space and with no variables of its own because they are global as well it sort of effs the pooch for that. :( Welcome to the world of multi-threading in windows. :/
Too bad I can't just have my functions all set up nice and neat and be able to have XX function in a certain namespace run in its own thread but I have never been able to achieve it nor anything I have read said I could. If you know different then please enlighten me. :)

Anyways this is getting a tad out of scope because I have had .cpp and .h with globals before so that isn't it anyways though I still would like to be enlightened if you know how I could do multi-threads without it being in a global space on Windows.