I have defined a function within a header file. In debug, it compiles and links fine. In release, I get the compile error "multiple definition of `blah::blah(blah& blah)'" for every object file of every class that includes the header.
I'm using gcc-4.8.1. I can't post up the actual code, this version has names changed to protect the innocent:
#ifndef INCLUDE_SMELLS_FUNNY
#define INCLUDE_SMELLS_FUNNY
#include "ParentClass.h"
#include "ChildClassA.h"
#include "ChildClassB.h"
namespace someplace {
bool smellsFunny(const ParentClass& someData) {
// All ChildClass As smell funny
if(dynamic_cast<const ChildClassA*>(&someData)) {
return true;
}
// If ChildClass B, need to check if smells funny
const ChildClassB* childB = dynamic_cast<const ChildClassB*>(&someData)
if(childB) {
return childB->MoreThanAWeekOld();
}
// Default is smells OK
return false;
}
}
#endif // INCLUDE_SMELLS_FUNNY
I haven't been able to find which gcc flag is responsible.
Of course, a fix is just to move the implementation into a cpp file. But why is this necessary? Why does this happen only in release?
It's because you define the function in a header file, and then include that header file in multiple source files. That means the function will be defined in each source file (technically, translation unit) where you include the header.
There are a couple of solutions to this:
Mark the function as static. That means that each definition in the translation units will not be exported.
Mark the function as inline. This works basically the same as the first alternative.
Put the definition of the function in a source file, and only have its declaration in the header file.
For a small function like the one you have, then alternative 2 might be a good one. If you have a larger function, that can't easily be inlined, you should go with alternative 3.
Also, if you go with number 3, then you don't need to include the header files, and then lessen the risk of circular inclusion.
Since you have placed the function definition in the header, you need to mark it inline:
inline bool smellsFunny(const ParentClass& someData) { ...
This is because every place in which you include the header will have a definition of the function, breaking the one definition rule (ODR). inline lets you work around the ODR.
As to why there is no problem in release mode, that doesn't make sense: the code is not correct. It could be that release mode is declaring the function inline for you.
I can not say exactly but maybe in the debug mode the function is considered as inline function.
If the function is in a header file, you need to declare it inline, unless it's defined within a class.
Related
I have a c++ header file containing a class.
I want to use this class in several projects, bu I don't want to create a separate library for it, so I'm putting both methods declarations and definitions in the header file:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
#endif
If inside the same project I include this header from more than one cpp file, I get an error saying "multiple definition of test_ns::TestClass::testMethod()", while if I put the method definition inside the class body this does not happen:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod(){
// some code here...
}
};
} // end namespace test_ns
#endif
Since the class is defined inside a namespace, shouldn't the two forms be equivalent? Why is the method considered to be defined twice in the first case?
Inside the class body is considered to be inline by the compiler.
If you implement outside of body, but still in header, you have to mark the method as 'inline' explicitly.
namespace test_ns{
class TestClass{
public:
inline void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
Edit
For myself it often helps to solve these kinds of compile problems by realizing that the compiler does not see anything like a header file. Header files are preprocessed and the compiler just sees one huge file containing every line from every (recursively) included file. Normally the starting point for these recursive includes is a cpp source file that is being compiled.
In our company, even a modest looking cpp file can be presented to the compiler as a 300000 line monster.
So when a method, that is not declared inline, is implemented in a header file, the compiler could end up seeing void TestClass::testMethod() {...} dozens of times in the preprocessed file. Now you can see that this does not make sense, same effect as you'd get when copy/pasting it multiple times in one source file.
And even if you succeeded by only having it once in every compilation unit, by some form of conditional compilation ( e.g. using inclusion brackets ) the linker would still find this method's symbol to be in multiple compiled units ( object files ).
These are not equivalent. The second example given has an implicit 'inline' modifier on the method and so the compiler will reconcile multiple definitions itself (most likely with internal linkage of the method if it isn't inlineable).
The first example isn't inline and so if this header is included in multiple translation units then you will have multiple definitions and linker errors.
Also, headers should really always be guarded to prevent multiple definition errors in the same translation unit. That should convert your header to:
#ifndef EXAMPLE_H
#define EXAMPLE_H
//define your class here
#endif
Don't put a function/method definition in an header file unless they are inlined (by defining them directly in a class declaration or explicity specified by the inline keyword)
header files are (mostly) for declaration (whatever you need to declare). Definitions allowed are the ones for constants and inlined functions/methods (and templates too).
Actually it is possible to have definitions in a single header file (without a separate .c/.cpp file) and still be able to use it from multiple source files.
Consider this foobar.h header:
#ifndef FOOBAR_H
#define FOOBAR_H
/* write declarations normally */
void foo();
void bar();
/* use conditional compilation to disable definitions when necessary */
#ifndef ONLY_DECLARATIONS
void foo() {
/* your code goes here */
}
void bar() {
/* your code goes here */
}
#endif /* ONLY_DECLARATIONS */
#endif /* FOOBAR_H */
If you use this header in only one source file, include and use it normally.
Like in main.c:
#include "foobar.h"
int main(int argc, char *argv[]) {
foo();
}
If there're other source files in your project which require foobar.h, then #define ONLY_DECLARATIONS macro before including it.
In use_bar.c you may write:
#define ONLY_DECLARATIONS
#include "foobar.h"
void use_bar() {
bar();
}
After compilation use_bar.o and main.o can be linked together without errors, because only one of them (main.o) will have implementation of foo() and bar().
That's slightly non-idiomatic, but it allows to keep definitions and declarations together in one file. I feel like it's a poor man's substitute for true modules.
Your first code snippet is falling foul of C++'s "One Definition Rule" - see here for a link to a Wikipedia article describing ODR. You're actually falling foul of point #2 because every time the compiler includes the header file into a source file, you run into the risk of the compiler generating a globally visible definition of test_ns::TestClass::testMethod(). And of course by the time you get to link the code, the linker will have kittens because it will find the same symbol in multiple object files.
The second snippet works because you've inlined the definition of the function, which means that even if the compiler doesn't generate any inline code for the function (say, you've got inlining turned off or the compiler decides the function is too big to inline), the code generated for the function definition will be visible in the translation unit only, as if you'd stuck it in an anonymous namespace. Hence you get multiple copies of the function in the generated object code that the linker may or may not optimize away depending on how smart it is.
You could achieve a similar effect in your first code snippet by prefixing TestClass::testMethod() with inline.
//Baseclass.h or .cpp
#ifndef CDerivedclass
#include "Derivedclass.h"
#endif
or
//COthercls.h or .cpp
#ifndef CCommonheadercls
#include "Commonheadercls.h"
#endif
I think this suffice all instances.
Okay so I recently learned how the compiler exactly works and what the "linker" is. From the tutorial videos I've watched I clearly saw that if I include more than once a declaration, to say:
void Log(const char* message);
I would get an error since I am declaring it more than once. But currently, as I am testing it, I've created a header file which contains that particular declaration and I've included it a couple of times in my Main compilation unit, as so:
#include "Log.h"
#include "Log.h"
I have removed the #pragma once statement, nor do I have header guards written, but my program still runs perfectly and without any problems. Since the videos are 2-3 years old, I thought maybe there has been an update, which alltogether removes the need of guards and pragmas, but I do not know for sure.
The tutorials you've seen are correct. You cannot have more than one definition of something unless you use special techniques.
In this case though you don't have a definition.
void Log(const char* message);
is a declaration and you are allowed to have multiples of those. If you change the code to
void Log(const char* message) {}
then you would have a function definition and will get an error.
I would get an error since I am declaring it more than once.
Re-declaration is generally allowed, as long as you don't mix different kinds of declarations with the same name. Following is perfectly legal C++, and always has been:
void Log(const char* message);
void Log(const char* message);
You may have been confused with the one definition rule, which disallows defining things more than once.
I have removed the #pragma once statement, nor do I have header guards written, but my program still runs perfectly and without any problems.
If your header doesn't define anything, then it doesn't need a header guard. It's however simpler to just conventionally always keep the guard so that there is no need to keep track of whether there are definitions or not.
Bonus answer: All definitions are also declarations. It is usually easy to distinguish definitions of classes and functions from forward declarations:
return_type function_name(argument_list); // not a definition of function
return_type function_name(argument_list) { ... } // is a definition of function
class class_name; // not a definition of class
class class_name { // is a definition of class
void member_function(); // not a definition of function
void inline_member_function() { ... }; // is a definition of function
};
void class_name::member_function() { ... } // is a definition of function
Distinguishing variable definitions is a bit harder. Always check the rules when unsure.
this a function forward declaration and you just let the compiler know that a function X will be defined later. in some resources you will find out it's written/said that multiple declaration isn't allowed, but i think cuz of the clean code approach, not a compiler issue. and your case, you just include the declaration twice, the same if you declared the function in two different header files and included both of them in a source file.
Cherno's tutorials?
I think its made crystal clear in the videos that you can't have multiple definitions of a function. The custom header files that you've created are basically chunks of code copy-pasted hence if they include different definitions of the same function or say class it will result in ambiguity and throw an error as expected.
Edit: The point that he wanted to make -
If you write those two same function definitions together in a file then obviously it will throw up an error due to ambiguity arising as I mentioned above, which is detected by the compiler, since its only in a single file.
But when you place those two same definitions in a different file, say your custom created header "log.h" then when you import them into your cpp file twice (or say you import them in another cpp file and build the solution like in visual studio) it will throw up a linker error as the linker is involved (multiple files - wherein the job of the linker is to link them into a combined executable) and it cannot select multiple definitions present in different files. Hence for this case you will get the multiple definitions/signature error. (And including pragmas suppress warnings)
A Solution to resolve that is making the functions static, so that they are defined internally or only for the file they are being compiled against. This makes it possible to have multiple function definitions of the same function in different files with no linking error. Another option is to make it in-line. These cases provide you with multiple definitions with no errors, otherwise it will throw up errors.
For C programs, I know I need .h, and .cpp to allow multiple .h to be read and compiled together but linked later.
However, for C++, I don't want to break up the class member function declaration and definition to two parts. Although it is the typical C++ way, I am trying to merge member function declaration and definition in one header file. I saw some people doing that. I would like to know if there is any problem to do this.
I know all members defined in .h class definition are then inline functions, but can they be non-inline in any way? Will compiler be controllable so that they don't have to be inline, for example, when the function is huge?
The VS2015 intellisense shows error when the 2s is in a member function defined in header file, but doesn't show that in cpp file. But it compiles. Is it showing that I am doing it wrong, or it's a bug for VS2015? I deleted the sdf, restarted the project, as long as copy the function into the .h file, it shows a read line under std::this_thread::sleep_for(2s);
see
class testtest {
void tryagain() {
using namespace std::chrono_literals;
auto twosec = 2s;
std::this_thread::sleep_for(2s);// problem is here
}
};
Is compiling faster if we separate the .h and .cpp?
My final compiler would be g++4.9.2, and I am using VS2015 to test build. The final code will run on an ARM with 1GB RAM on Linux.
I don't intend to argue about wich style is better, but hope to focus on whether it works, and what are the trade offs.
It is perfectly fine to place all implementation code in the .h file if you want, it usually depends on the situation. It's usually good practice to split up the interface and implementation even if all the code is in the .h file by doing something like this
class MyClass {
public:
void doSomethingUseful();
};
....
void MyClass::doSomethingUseful() {
// code goes here....
}
Not all functions will automatically be inlined, the compiler usually decides what to inline or not. Larger functions will likely not be inlined even if they're in the header. You can use the inline keyword to give a hint to the compiler that you'd like the function to be inlined but this is no guarantee (also as a small aside, functions marked as inline in a .cpp file will be inlined, but only when called from other functions within that same .cpp file)
Compile times will be slower with more code in the .h file so it's best to try and reduce the amount of code in them as much as possible. I guess in your case though it shouldn't be that noticeable.
I hope that is of some help! :)
You can put defines around functions to prevent them being implemented more than once
header file:-
class MyClass {
public:
void doSomethingUseful();
};
// inline functions
....
// non inline function
#ifdef MYCLASSCPP
void MyClass::doSomethingUseful() {
// code goes here....
}
#endif
Then define MYCLASSCPP in just one CPP file. (or complier parameter).
I am starting to learn C++ and am getting this compilation error from my IDE (CodeBlocks). I don't understand why this is happening.
|2|multiple definition of `parser::parseFile()'
|2|first defined here|
I don't see how this could happen. This is my entire code base.
main.cpp
#include "parser/parser.cpp"
int main()
{
return 0;
}
parser/parser.cpp
namespace parser {
void parseFile() {
}
}
Assuming you compiled both main.cpp and parser/parse.cpp you clearly have two definitions of parser::parseFile(): the #include directive just become replaced by the content of the named file (you can use the -E flag with your compiler to see the result).
You probably meant to declare parser::parseFile() in a header file (typically with a suffix .h or .hpp or something like that):
// file: parser/parser.hpp
#ifndef INCLUDED_PARSER_PARSER
#define INCLUDED_PARSER_PARSER
namespace parser {
void parseFile();
}
#endif
... and to include this header file into both translation units.
Your program have violated the One Definition Rule (also known as ODR).
In short, parser::parseFile function have been defined in both of your .cpp files, because on the compiler level, #include <header.h> simply means substituting the entire file contents in place.
Solution to your problem depends on your actual program, though. If you want to solve the ODR rule for class definitions, you can do either of:
1) Add a #pragma once at the beginning on a header. This, although being supported by all major compilers, is not standardized way of protecting from double-including a header.
2) Add an include guard:
#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD
// your header contents go here
#endif
If you want to solve the ODR problem for functions and data variables, the above approach won't work because you can still have them defined multiple times in different .cpp files.
For this, you still have 2 options:
1) define your function somewhere outside, namely, in some .cpp file, only leaving its declaration in the header:
// header.h
namespace parser {
void func();
}
// file.cpp
void parser::func() { ... }
2) Declare your function as inline, as inline function are allowed to have multiple definitions by the C++ standard (however, they must be strictly identical up to lexem level):
// header.h
namespace parser {
inline void func() { ... }
}
To sum it up, I'd strongly recommend you go both directions by protecting your header from double inclusion and making sure your function is either inline or gets defined in a .cpp file. With the latter, if your function implementation changes, you won't have to recompile all the files that include your header, but only the one that has the functon definition.
Header files ending with .h(usually) is often used to separate class and function declaration from their implementation.
In Code::Blocks you can add header files by right clicking on your project name -> 'Add files' -> create a new file with .h extension. Following good practise, you should also create a .cpp file with the same name where the implementation is written.
As already answered, in your header file you can first write an include guard followed by your include's (if any) and also your function declarations. And in your 'parser.cpp' & 'main.cpp' you will have to #include "parser.h" since the files depend on eachother.
I have C++ project which consists of multiple (in fact many) .cpp and .h files. While writing header files i have a file as follows
For eg MyHeaderFile.h
#ifndef _MYHEARDERFILE_H
#define _MYHEARDERFILE_H
// Here i have function defintion.
void myFunc() {cout << "my function" << endl; }
#endif
Above file is included in multiple files. While compiling i have getting "multiple definition of "myfunc" error.
I am expecting the header is included only once as i have #ifndef check so i am expecting error should not be thrown.
For example in case of templates we have to define in header file, in this case how we can avoid the problem i am facing now?
Can any one please help me why i am seeing the error? is my understanding right?
Thanks!
Normally, one puts function declarations in header files, and function definitions (i.e. the actual function body/implementation) in source files. Otherwise, you get exactly the issue you're seeing: the header file is #included (i.e. substituted) into multiple source files, so the function ends up being defined multiple times. This confuses the linker, so it complains.
The header-guard #ifndef ... stuff only prevents a header from being substituted into the same source file multiple times. Remember that each source file is compiled completely independently from all the others; all #defines and other definitions are "reset" for each one.
One possible alternative solution is to leave the function definition in the header file, but simply to mark it inline (this has the side-effect of eliminating the linker error). But, personally, I wouldn't do that.
Every function must be defined only once in a single translation unit (this is called One definition rule, and applies not only to functions). By placing the definition in a header which is then included, you are violating this rule.
You can simply leave the declaration
void myFunc();
in the header, and define myFunc in a .cpp which provides the definition.
Otherwise you can declare your function inline.
Note that when using templates, instead, you are usually led (for template-related specific issues) to place definitions directly in the headers, which could appear surprising given the problems you are facing now.