Multiple declaration problem
Hello. I have a problem with multiple declaration in a project I am working on. I have constructed a similar testcase which throws the same kind of error. Please see the files in the attachment. -g or -g3 did not give any useful debugging symbols, I don't know why. The following is the session transcript:
$ ls main.cpp myheader.cpp myheader.h $ g++ -c main.cpp $ g++ -c myheader.cpp $ g++ -o main main.o myheader.o myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit status $ mv main.cpp main.c $ mv myheader.cpp myheader.c $ rm *.o $ gcc -c main.c $ gcc -c myheader.c $ gcc -o main main.o myheader.o myheader.o:(.rodata+0x0): multiple definition of `a' main.o:(.rodata+0x0): first defined here myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit status
In my project, I need to put the following statement in a header file:
int lawCurrentEngine = NONE ; // NONE has been enum-med previously
because I need to declare a function
int lawCloseEngine ( int engineID = lawCurrentEngine ) ;
I include the header file containing these two lines in two cpp files, and I get a multiple definition error for lawCurrentEngine just like in the given test case. If I push the lawCurrentEngine declaration to one of the cpp-s (it's not needed in the other cpp) I am unable to provide the default argument for the lawCloseEngine which can be done only in the header.
I don't understand how I am getting such an error when I have used the #ifndef #define #endif technique as per good programming practice.
Please help,
Thanks.
Shriramana Sharma.
Quoted 32 lines · Shriramana Sharma
Hello. I have a problem with multiple declaration in a project I am working on. I have constructed a similar testcase which throws the same kind of error. Please see the files in the attachment. -g or -g3 did not give any useful debugging symbols, I don't know why. The following is the session transcript:
$ ls main.cpp myheader.cpp myheader.h $ g++ -c main.cpp $ g++ -c myheader.cpp $ g++ -o main main.o myheader.o myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit status $ mv main.cpp main.c $ mv myheader.cpp myheader.c $ rm *.o $ gcc -c main.c $ gcc -c myheader.c $ gcc -o main main.o myheader.o myheader.o:(.rodata+0x0): multiple definition of `a' main.o:(.rodata+0x0): first defined here myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit statusIn my project, I need to put the following statement in a header file:
int lawCurrentEngine = NONE ; // NONE has been enum-med previously
because I need to declare a function
Quoted 8 lines
int lawCloseEngine ( int engineID = lawCurrentEngine ) ;
I include the header file containing these two lines in two cpp files, and I get a multiple definition error for lawCurrentEngine just like in the given test case. If I push the lawCurrentEngine declaration to one of the cpp-s (it's not needed in the other cpp) I am unable to provide the default argument for the lawCloseEngine which can be done only in the header.
Default parameter values need to be constants; if you declare lawCloseEngine as "const int", you won't get an error.
If you want the default value to be a variable rather than a constant, you need to use something like:
int lawCloseEngine ( int engineID = -1 ) ;
int lawCloseEngine ( int engineID )
{
if (engineID == -1)
engineID = lawCurrentEngine ;
...
}Alternatively, define separate zero-arguments and one-argument versions of lawCloseEngine.
Signature · 1 line
Glynn Clements <[email protected]>
The problem, as I understand it, is that you are instantiating a variable in a header and you need it's value in another header.
It seems that the best solution would instead be to move the variable instantiation into the source file, keep the declaration in the header if you still need visibility. To synchronize the value of the variable and the function, you should use a #define or const. Using a variable will not give you a dynamic default anyway, as it is evaluated at compile time. Try something like this:
in the header:
#define DEFAULT_ENGINE = NONE //could use const int CURRENT_ENGINE int lawCurrentEngine; //declaration only, if you need it
in source:
lawCurrentEngine = DEFAULT_ENGINE; // NONE has been enum-med previously
in other header:
int lawCloseEngine ( int engineID = DEFAULT_ENGINE );
Now that I've written this, it looks like you may be trying to get a dynamic default. You can't actually do that, but you can get close with a file static variable. i.e.:
in source:
static currentEngine = NONE;
int lawCloseEngine( int engineID = NONE ) {
if( engineID == NONE ){
if (currentEngine != NONE) lawRealCloseEngine(currentEngine);
currentEngine = NONE;
return SUCCESS;
} else {
lawRealCloseEngine(engineID);
return SUCCESS;
}
return FAIL; //Should never happen.
}Hope this helps
Jesse Ruffin
AJP Services
Quoted 49 lines · Shriramana Sharma
Hello. I have a problem with multiple declaration in a project I am working on. I have constructed a similar testcase which throws the same kind of error. Please see the files in the attachment. -g or -g3 did not give any useful debugging symbols, I don't know why. The following is the session transcript:
$ ls main.cpp myheader.cpp myheader.h $ g++ -c main.cpp $ g++ -c myheader.cpp $ g++ -o main main.o myheader.o myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit status $ mv main.cpp main.c $ mv myheader.cpp myheader.c $ rm *.o $ gcc -c main.c $ gcc -c myheader.c $ gcc -o main main.o myheader.o myheader.o:(.rodata+0x0): multiple definition of `a' main.o:(.rodata+0x0): first defined here myheader.o:(.data+0x0): multiple definition of `b' main.o:(.data+0x0): first defined here collect2: ld returned 1 exit statusIn my project, I need to put the following statement in a header file:
int lawCurrentEngine = NONE ; // NONE has been enum-med previously
because I need to declare a function
int lawCloseEngine ( int engineID = lawCurrentEngine ) ;
I include the header file containing these two lines in two cpp files, and I get a multiple definition error for lawCurrentEngine just like in the given test case. If I push the lawCurrentEngine declaration to one of the cpp-s (it's not needed in the other cpp) I am unable to provide the default argument for the lawCloseEngine which can be done only in the header.
I don't understand how I am getting such an error when I have used the #ifndef #define #endif technique as per good programming practice.
Please help,
Thanks.
Shriramana Sharma.
Thanks to all who replied.
I found a different solution, which is by declaring the variables static. Find attached solutions.
But still the C parser (or what is it?) did throw up an error with the const variable, which C++ did not.
@Andre: Is there any I should not declare a variable in a header file if I want that variable to be visible to many cpp files? I can avoid writing many "extern" lines by using static.
Thanks again,
Shriramana.
Quoted 5 lines · Shriramana Sharma
I found a different solution, which is by declaring the variables static. Find attached solutions.
But still the C parser (or what is it?) did throw up an error with the const variable, which C++ did not.
In C, "const" is only valid for pointer and array targets, not for primitive types or structures.
Quoted 3 lines
@Andre: Is there any I should not declare a variable in a header file if I want that variable to be visible to many cpp files? I can avoid writing many "extern" lines by using static.
Presumably, you mean "define a variable"; a declaration (e.g. "extern int foo") merely tells the compiler that the variable exists, and its type, while a definition actually creates the variable.
If you define a variable in a header file, each object file will get a separate copy of the variable. All of the variables will have the same name, but they will be different variables; modifying one won't affect any of the others.
This is fine for a constant (unless it occupies a lot of memory, in which case you don't want to include a separate copy in each object file), but not for a variable.
Signature · 1 line
Glynn Clements <[email protected]>