Register | Login | |||||
Main
| Memberlist
| Active users
| ACS
| Commons
| Calendar
| Online users Ranks | FAQ | Color Chart | Photo album | IRC Chat |
| |
0 user currently in Programming. | 3 guests |
Acmlm's Board - I2 Archive - Programming - C++: Bizarre Multiple Declarations | | | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread |
User | Post | ||
beneficii Lakitu Level: 36 Posts: 384/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Alright, I'm working on a project in C++ that has multiple source files with the same header file between them. Any variable I declare specific to a source file I declare as static (i.e. that is only for that source file) and any variable that is shared between source files is declared in the header file (not as static) I would think that most here would agree that this is standard practice in really big projects. Now, I've tried compiling my project, I've gone through and corrected all syntax editors and it looks like I'm finally going to get it to compile when BAM! a very looooong list of linker errors shows up. They all said: multiple definition of 'variable' first defined here (I'm using Bloodshed Dev C++ v. 4.9.9.2 btw and its default compiler GNU C++ Compiler.) After that, I look at those variables and I see that they are all declared in the header file! I go to the compile log and see basically this: sourcefileB.cpp: multiple definition of 'variableJ' // again variableJ is declared only in the header file sourcefileA.cpp: first defined here sourcefileC.cpp: multiple definition of 'variableJ' sourcefileA.cpp: first defined here sourcefileD.cpp: multiple definition of 'variableJ' sourcefileA.cpp: first defined here I'm thinking, okay, why is there a conflict here? Doesn't the linker know that these variables were all declared in a header file that was simply used by all the source files? I wrote a much smaller program afterward with two source files and a header file, which was included in both source files. I declared some variables in the header file. When it compiled, there was no conflict and the program ran normally. I'm wondering, What makes my program so different? Is it a problem with the compiler, or is there perhaps a common trap that I'm falling for? Can any of you perhaps help me? Thanks. |
|||
neotransotaku Baby Mario 戻れたら、 誰も気が付く Level: 87 Posts: 3767/4016 EXP: 6220548 For next: 172226 Since: 03-15-04 From: Outside of Time/Space Since last post: 11 hours Last activity: 1 hour |
| ||
try placing this as the first two lines of the shared header file #ifdef __headerfile #define __headerfile and this as the end of the shared header file #endif usually this is the techinique to ensure a header file is included only once |
|||
beneficii Lakitu Level: 36 Posts: 386/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Originally posted by neotransotaku Hold on. Nope, if I do it #ifdef __headerfile, then __headerfile will never get defined. I tested it out anyway, and when I compiled the program it said that none of the variables defined in the header file were defined. I next tried #ifndef __headerfile, which seemed more logical, but still had the problem of multiple declarations. I counted the same number of underscores and everything. I wonder what's wrong. (edited by beneficii on 08-06-05 02:37 AM) (edited by beneficii on 08-06-05 02:43 AM) |
|||
HyperLamer <||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people Sesshomaru Tamaranian Level: 118 Posts: 6326/8210 EXP: 18171887 For next: 211027 Since: 03-15-04 From: Canada, w00t! LOL FAD Since last post: 2 hours Last activity: 2 hours |
| ||
Yeah, #ifndef, not #ifdef. That should do it. Are these source files all part of the same project, though? If they are, you should only need to include the header once, not in each file. |
|||
neotransotaku Baby Mario 戻れたら、 誰も気が付く Level: 87 Posts: 3770/4016 EXP: 6220548 For next: 172226 Since: 03-15-04 From: Outside of Time/Space Since last post: 11 hours Last activity: 1 hour |
| ||
yeah, i mean't #ifndef as for issues of multiple declarations, the only thing I can think of is how exactly you are organizing your files... |
|||
Dish Spiny Level: 38 Posts: 500/596 EXP: 355646 For next: 14801 Since: 03-15-04 From: Disch Since last post: 18 days Last activity: 18 days |
| ||
If you define a variable to be global, it will have global scope (Global meaning it exists for the whole program). If you #include a header file which has a var declaration in several .cpp files, each .cpp file will create its own variable with the same name. This is where your problems are coming from. The solution here is to make the variable once, then link it so that all .cpp files have access to it.
Of course extern int myVar will only work if 'int myVar' is declared somewhere in your program. For a halfway decent analogy of why it works this way... making the actual variable (int myVar) actaully makes the variable with a "body". Similar to how making a function with a body gives the function it's body. If you have a function in your program which has several bodies, you'll get errors much like the ones you were getting -- because you were making several different variables which have the same body -- and the compiler doesn't know which one you want to use. Making it 'extern' says "okay, this variable exists... but not in this .cpp file, so we'll link to it, but it won't be in this compile" -- which is kind of like a body-less variable. Equivilent to having a function prototype (function without a body). It's making the function/var available for use, but without actually making it. Of course if you actually call the function, it will need to have a function body found at link time. Likewise if you actually use an extern var, it will need to find a var body at link time. Otherwise you get errors. So yeah, only 1 cpp file has the variable. The others use 'extern' to link to that var. Yeah it's a pain in the ass -- which is one of the reasons why I avoid global vars like the plague. EDIT: To avoid a pain in the ass, you can sort of cheat with clever use of #defines
That'll make it easier to manage a large file full of global vars. The #define _EXTERN saves you from having to make (and maintain) two sets (bodied and body-less) since it keeps both in the same file. (edited by Disch on 08-06-05 11:25 AM) (edited by Disch on 08-06-05 11:41 AM) (edited by Disch on 08-06-05 11:49 AM) |
|||
beneficii Lakitu Level: 36 Posts: 387/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Originally posted by Disch That'll make it easier to manage a large file full of global vars. The #define _EXTERN saves you from having to make (and maintain) two sets (bodied and body-less) since it keeps both in the same file. Okay, so I would have to add _EXTERN in front of every variable in the header file? Also, put in DO_NOT_MAKE_EXTERN and DO_NOT_MAKE_EXTERNS or was that a typo? Thanks. |
|||
Dish Spiny Level: 38 Posts: 501/596 EXP: 355646 For next: 14801 Since: 03-15-04 From: Disch Since last post: 18 days Last activity: 18 days |
| ||
Originally posted by beneficii Yes. That will make it bodied or body-less depending on whether or not DO_NOT_MAKE_EXTERNS was defined before including the header.
sorry, that was a typo. It doesn't matter what it is as long as it's the same thing both times. *me goes to edit post to correct that* (edited by Disch on 08-06-05 12:00 PM) |
|||
beneficii Lakitu Level: 36 Posts: 388/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Originally posted by DischOriginally posted by beneficii I think I understand what this does. If DO_NOT_MAKE_EXTERN is defined, then it defines __EXTERN as nothing, which makes the variable normal. If it's not defined, then it defines __EXTERN as extern, which makes the variable extern. You only want it one source without the extern, while everyone else should have it, so you define DO_NOT_MAKE_EXTERN for it. Thanks. EDIT: Ugh this is so frustrating! I did as you said, and it did something new. First, it said: [Warning] 'vars' initialized and declared 'extern' // for each variable in the header file then it went right back to complaining about multiple declarations as it did before. I declared DO_NOT_MAKE_EXTERN in one file (and it was for that file ("in file included from file") I didn't get the warnings). Do you have any recommendations? (edited by beneficii on 08-06-05 12:18 PM) |
|||
Dish Spiny Level: 38 Posts: 502/596 EXP: 355646 For next: 14801 Since: 03-15-04 From: Disch Since last post: 18 days Last activity: 18 days |
| ||
don't init the var when it's declared. int myvar = 5; <--- don't do that, it won't like it when the var is extern Instead init all your vars at program startup -- like call an Init() function or something which sets everything to what you want it to be. |
|||
beneficii Lakitu Level: 36 Posts: 389/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Originally posted by Disch Uh, well, that's going to take some time to correct, because those vars are meant to be constant arrays, but I'll see what I can do. |
|||
Dish Spiny Level: 38 Posts: 503/596 EXP: 355646 For next: 14801 Since: 03-15-04 From: Disch Since last post: 18 days Last activity: 18 days |
| ||
If they're constant then declare them as constant and then you don't have to worry about that extern crap: const int myArray[5] = {0,1,2,3,4}; that should work fine. If you still get problems (which I doubt), try making it static as well: static const int myArray[5] = {0,1,2,3,4}; |
|||
beneficii Lakitu Level: 36 Posts: 390/567 EXP: 299656 For next: 8454 Since: 06-27-04 From: Cordova, TN, USA Since last post: 14 hours Last activity: 6 hours |
| ||
Originally posted by Disch Okay, thank you! I should have seen that! If a variable is initialized in the declaraqtion it won't let it be extern. Thank you! It now compiles succesfully. Onto the next stage of my program and arguably the most challenging: the logic tests! |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread |
Acmlm's Board - I2 Archive - Programming - C++: Bizarre Multiple Declarations | | | |