Multiple definition of namespace function [duplicate] - c++

This question already has answers here:
multiple definition in header file
(4 answers)
Closed 4 years ago.
I just can't get my head around why this won't compile.
I have three files:
main.cpp
#include "expression.h"
int main(int argc, char** argv)
{
return 0;
}
expression.h
#ifndef _EXPRESSION_H
#define _EXPRESSION_H
namespace OP
{
char getSymbol(const unsigned char& o)
{
return '-';
}
};
#endif /* _EXPRESSION_H */
And expression.cpp
#include "expression.h"
(Ofc there is more inside of it, but even if I comment everything except for the #include out it doesn't work)
I compile it with
g++ main.cpp expression.cpp -o main.exe
This is the error I get:
C:\Users\SCHIER~1\AppData\Local\Temp\ccNPDxb6.o:expression.cpp:(.text+0x0): multiple definition of `OP::getSymbol(unsigned char const&)'
C:\Users\SCHIER~1\AppData\Local\Temp\cc6W7Cpm.o:main.cpp:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
The thing is, it seems to parse expression.h two times. If I just compile it using main.cpp OR expression.cpp I don't get the error. The compiler just ignores my #ifndef and continues...
Any clues?

The thing is, it seems to parse expression.h two times.
Of course it does. You include it in two different cpp files. Each inclusion dumps the content of the header into that translation unit, so you get two definitions of the same function, making the linker rightfully complain. This has nothing to do with include guards, which protect you from accidentally including twice in the same file.
You can, however, have a function defined in a header. So long as it's marked inline. So do this:
namespace OP
{
inline char getSymbol(const unsigned char& o)
{
return '-';
}
}
inline here is a promise that all of those functions are the exact same one, to the letter. So the multiple definitions are in fact considered one and the same. Be careful not to break this promise however (don't use any construct that can change the function body depending on where it's included).
And by the way, a namespace doesn't need to be terminated with a ;, so I took the liberty of removing it.

Related

Getting 'multiple definition' error and I have no clue why [duplicate]

This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.

Why can't I just define a non-const gloabal variable in header? and if I use namespaces why do I have to declare it 'extern'?

1) I know a non-const variable is external linkage by default (it's like it's been declared as external more or less) but i don't understand why can't i define a global variable such as int glbl_a in header
//test.h
#ifndef TEST_H
#define TEST_H
int glbl_a=0; //wrong -> "multiple definition of `glbl_a`"
static int st_glbl_a=1; //ok to initialize it in header!
extern int ext_glbl_a; //ok to declare it and define it in test.cpp
#endif
//test.cpp
#include "test.h"
using namespace std;
//st_glbl_a=22; i could use st_glbl_a but it wouldn't affect st_glbl_a in main cause of 'static'
int ext_glbl_a=2; //definition of external gloabal non-const variable
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
extern int glbl_a; //declaration of glbl_a external
int main(){
cout<<glbl_a;
}
the working version for this program is the one in which I define int glbl_a=0; in test.cpp only and declare extern int glbl_a; in main before using it in output (definition in test.h is just commented, that is there's nothing about glbl_a).
2)the working version doesn't work anymore if I group all definitions/declaretions into a namespace spread onto test.cpp and test.h (MyNamespace) cause of int glbl_a in test.cpp:
//test.h
#ifndef TEST_H
#define TEST_H
namespace MyNamespace{
//extern int glbl_a;
}
#endif
//test.cpp
#include "test.h"
using namespace std;
namespace MyNamespace{
int glbl_a=0;
}
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
int main(){
cout<<MyNamespace::glbl_a; //wrong -> "'glbl_a' is not a member of 'MyNaspace'"
}
it would work only if I de-comment declaration in test.h, but why?
Problem 1
Including a header effectively pastes the included file into the including file, producing one large file that is then compiled (and, typically, promptly deleted). This means that every including file now has its very own glbl_a. The compiler is happy, but when the linker attempts to put everything together, it finds many equally valid pretenders to the name glbl_a. The linker hates this and doesn't even try to figure out what you're trying to do. It simply spits out an error message and asks that you fix the problem.
Problem 2
test.cpp and main.cpp are different translation units. They compile to produce different, completely independent objects. Neither can see what's in the other, so the fact that MyNamespace::glbl_a exists in test.cpp is lost on main.cpp. When main.cpp is compiled, the compiler builds a list of identifiers declared in the file constructed from main.cpp and all of its included headers. MyNamespace::glbl_ais never declared as of when it is first used (or after for that matter) so the compiler spits out an error message.
Uncommenting the declaration in test.h means the compiler will find MyNamespace::glbl_a in main.cpp and will allow it's use. Since MyNamespace::glbl_a is defined in test.cpp the linker can find one-and-only-one MyNamespace::glbl_a and can successfully link.
extern does not allocate storage. Instead it is a promise to the compiler that the variable being declared will be fully defined and allocated somewhere else, maybe later in the file or in another file. The variable exists, somewhere, and compilation can continue. The linker will call you out as a liar if it cannot find a definition.
More details here: How does the compilation/linking process work?
More on extern: When to use extern in C++ and Storage class specifiers
headers will be included by other files (more than one) thus if you define in header, it will be in each translation unit thus lead to "multiple definition"

Solution to Multiple definition in C++

guys, this is my first question in StackOverflow so forgive me if make any mistake.
I am writing a small project which contains 2 source files and 3 header files.
// some_template_functions.h
#ifndef SOME_TEMPLATE_FUNCTION_H
#define SOME_TEMPLATE_FUNCTION_H
template <typename T>
int getvalue(string line, string key, T & val)
{
// method to get value (all the types except string) from line using key
}
template <>
int getvalue<string>(string line, string key, string &val)
{
// method to get some string from line using key, similar to getvale<int>
// but with slight difference to handle some special characters
}
#endif
//myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include "some_template_functions.h"
class MYCLASS
{
//declarations of constructors, member functions and members
double member_double;
string member_string;
}
#endif
//myclass.cpp
#include "myclass.h"
MYCLASS:MYCLASS()
{
// for each member
// using "getvalue" defined in "SOME_TEMPLATE_FUNCTION.H" to get the values
getvalue(line, key, member_double);
getvalue(line, key, member_string);
}
//main.cpp
#include "myclass.h"
#include "some_template_functions.h"
int main()
{
myclass A;
int some_value;
getvalue(line, key, value);
return 0;
}
I have no problem compiling the main.o and myclass.o but it is just when I was trying to link the two object files I got error message like:
myclass.cpp: multiple definition of int getvalue<std::basic_string><char, std::char_traits<char>, ...> and etc.
/tmp/cc22zEow.o:main.cpp: first defined here
collect2: ld returned 1 exit status
I know the reason probably is because I am including "some_template_function.h" in both myclass.h and main.cpp, each myclass.o and main.o is going to have its own definition of getvalue which is causing the problem. If I change
#include "some_template_functions.h"
to
#ifndef SOME_TEMPLATE_FUNCTIONS_H
#define SOME_TEMPLATE_FUNCTIONS_H
#endif
the constructors of MYCLASS is not goint to work.
I plan to expand the "some_template_functions.h" and its .cpp file in the future so if possible I would like to keep them separated from the other files. And because the way I am declaring function "getvalue" my attempt to move its definition to .cpp file was not working out for me very well.
I've tried to solve this problem for days but since I just start to learn C++ so far I could not get this right. So please, any suggestions will be appreciated! Thanks in advance!
The specialization of getvalue<std::string>(...) isn't a template and, thus, not implicitly inline. If you want to define this function in a header, e.g., because it is close to trivial and should be inlined, you'll need to mark it explicitly as inline. If the function does anything non-trivial it may be worth merely declaring the specialization in the header and defining it in a suitable translation unit.

Including .cpp files

I have read in places like here that you have to include .h files and not .cpp files, because otherwise then you get an error. So for example
main.cpp
#include <iostream>
#include "foop.h"
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
foop.h
#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif
foop.cpp
int foo(int a){
return ++a;
}
works, but if I replace #include "foop.h" with #include "foop.cpp" I get an error (Using Dev C++ 4.9.9.2, Windows):
multiple definition of foo(int)
first defined here
Why is this?
What include does is copying all the contents from the file (which is the argument inside the <> or the "" ), so when the preproccesor finishes its work main.cpp will look like:
// iostream stuff
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.
There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.
The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.
When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cpp and pasted it into main.cpp.
So when you compile main.cpp, the compiler emits a main.obj that contains the executable code for two functions: main and foo.
When you compile foop.cpp itself, the compiler emits a foop.obj that contains the executable code for function foo.
When you link them together, the compiler sees two definitions for function foo (one from main.obj and the other from foop.obj) and complains that you have multiple definitions.
This boils down to a difference between definitions and declarations.
You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.
In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.
Note: if you change foo to be static, you would have no linking errors. Despite the lack of errors, this is not a good thing to do.
You should just include header file(s).
If you include header file, header file automatically finds .cpp file.
--> This process is done by LINKER.
Because of the One Definition Rule (probably1).
In C++, each non-inline object and function must have exactly one definition within the program. By #includeing the file in which foo(int) is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).
You can make a function inline to override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #include a CPP file.
There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.
1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactly the same as the code you're compiling.
Because your program now contains two copies of the foo function, once inside foo.cpp and once inside main.cpp
Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
and foo.cpp
int foo(int a){
return ++a;
}
hence the multiple definition error
So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):
Visual Studios: .cpp file > right click > properties > configuration properties >
general > excluded from build > yes
I believe you can also exclude the file when compiling from the command line.
I want to clarify something: including header files is not neccessary to make the linker understand what you want. You can just declare it and it will be linked fine.
main.cpp:
#include <iostream.h>
//not including "foop.cpp"!
int foo(int a);
int main(){
std::cout << foo(4) << std::endln;
}
foop.cpp:
int foo(int a){
return a++;
}
I don't encourage doing like this, but know that headers are not some magic which you have to follow to make the code compile.
Using ".h" method is better
But if you really want to include the .cpp file then make foo(int) static in foo.cpp

a.h is included in b.h and I include b.h in my source file, do I need to include a.h in my source file as well?

I am going through an example in a c++ book. And did not understand a certain case.
The main.cpp includes stdexcept.h to use runtime exception. And also includes ErrorHandlingModule.h.
ErrorHandlingModule.h already includes stdexcept.h because of the runtime error parameter it has in the function prototype in it.
The book says I have to include stdexcept.h also in main.cpp. In the source code of the book it is also written that way.
When I remove sdtexcept.h from main.cpp compile passes just fine and program works ok still.
But why the book says that?
Thanks for any answers.
MAIN.CPP:
#include <iostream>
#include <stdexcept>
#include "ErrorHandlingModule.h"
#include "Prompt.h"
// ....
int main(int argc, char* argv[])
{
SAMSErrorHandlingModule::initialize();
do
{
try
{
char Operator = getOperator();
float Operand = getOperand();
cout << Accumulate( Operator, Operand ) << endl;
}
catch( runtime_error RuntimeError )
{
SAMSErrorHandlingModule::handleRuntimeError(RuntimeError);
}
catch(...)
{
SAMSErrorHandlingModule::handleNotaNumberError();
};
}while (SAMSPrompt::UserWantsToContinueYorN("More?"));
return 0;
}
ERRORHANDLINGMODULE.H
#include <stdexcept>
#ifndef _ERROR_HANDLING_MODULE_H
#define _ERROR_HANDLING_MODULE_H
namespace SAMSErrorHandlingModule
{
using namespace std;
void initialize( void );
int handleNotaNumberError( void );
int handleRuntimeError( runtime_error theRuntimeError );
}
#endif // _ERROR_HANDLING_MODULE_H
I think the reason is maintainance. At least, I would do that for this reason. If you eventually decide to switch to "ErrorHandlingModule.h" to something else (e.g. you implement a better error handling strategy and want to use the new one) you don't want the other code into main to break because of this.
This means that if you are using something from stdexcept in your main, apart from using it for input to/output from ErrorHandlingModule, you should include it. Otherwise, I would not include it, since it is not needed when ErrorHandlingModule is not used.
As you noted, this has nothing to do with compilation, as your program compiles just fine if you don't include it into the main. With this respect, however, notice that even if it compiles, it is not always "semantically" correct. In fact, your code might compile even if you remove the inclusion from "ErrorHandlingModule.h" (since stdexcept is included before including ErrorHandlingModule.h). This is the reason why I always prefer to have "..." includes before <...> ones.
Also check this question for a similar discussion.
No, you do not need the #include for stdexcept in both files. The pre-processor will copy the header file into the c file before running through the C compiler. Multiple includes of the same header file can be very problematic which is why the example code uses #ifndef for the header file you are creating to make sure that the header code is only included once. Like Stefano said though, if you no longer include stdexcept and then stop using the ERRORHANDLINGMODULE header file your code will no longer compile.