The following quote from c++ primer book confuse me a lot
Unlike other function, inline and constexpr functions may be defined
multiple times in the program. After all, the compiler needs the
definition, not just the declaration, in order to expand the code.
However, all of the definitions of a given inline or constexpr must
match exactly. As a result, inline and constexpr functions normally
are defined in headers.
-- C++ primer 5th Ed, 240 pp
"may be defined multiple times in the program" This quote confuse me a lot. As far as I understand, declaration can be made multiple time, but definition is only needed once.
can someone give me an example why there is a multiple definition.
In a header file (lets call it foo.h) you can have
inline int foo() { /* do stuff */ }
Now if you include foo.h in a couple cpp files then foo will be defined in each of them, which would be a multiple definition error. Since foo is marked as inline though, it is okay because all of the definitions are the same.
As far as I understand, declaration can be made multiple time, but definition is only needed once
The compiler works on translation units (basically a cpp file) and in it, it can do all sorts of optimizations but function inlining and constexpr require that the compiler know the definition of the function. That means each translation unit needs the definition of the function in it. We use inline to make that okay, otherwise it would be a multiple definition error.
As an example. This version isn't valid.
// main.cpp
inline int square(int num) {
return num * num;
}
inline int square(int num) {
return num * num;
}
int main()
{
return square(2);
}
https://godbolt.org/z/nlSbxg
But when you have it in multiple .cpp files (aka. translation units) it is ok because it is now linker job to do right thing.
// b.cpp
inline int square(int num) {
return num * num;
}
// main.cpp
inline int square(int num) {
return num * num;
}
int main()
{
return square(2);
}
Build: gcc main.cpp b.cpp
Same way works #include it will place code in those .cpp files that's all.
Of course if body of function is inlined, then nothing to link so no problem :)
If compiler decides to do an out-of-line version you end up with more than one object file (.o) having definition for the same "inline" function. Such definition will be marked.
Thanks to that mark linker won't yield that it has found multiple definitions and just pick first one that it finds.
So if all definitions are truly the same, then fine! We will get into troubles if we have different body of such function. Example in file b.cpp
// b.cpp
inline int square(int num) {
return 1;
}
It is undefined behavior to have multiple different definitions of the same inline function. It will compile of course but what we get? It depends on linker choice :D
I think the problem is that there are multiple things we can mean by "define." When you write an inline function in a header file, it's "defined" just once in the sense that there is only a single function with that name in your source code.
But that's not how the compiler and linker see the world. If you have an inline function foo in a header file that's called from a.cpp and b.cpp, then the complete compiled version of that function will be included in both a.obj and b.obj. The linker resolves the issue by picking just one of those compiled versions to include in your final binary.
Note that I'm glossing over significant details here, but this is the general idea (and what I think your textbook is eluding to).
Related
//myheader.h
namespace abc{
int func(int x) { return 10 + x;}
inline int callfunc(int a){ return func(a); }
}
//global.h
int func(int x){ return 10 + x; }
In the example above, when the code is compiled, and even if the inline function are not called at any place for now, it returns an error to resolve the ambiguity for the func(int x). Why doesn't inline function take the existing definition that is already present in the namespace abc?
Your error is not reproducible from posted code - these headers compile without problems when included in single .cpp file. So you really should post your .cpp files. It's .cpp files that are actually compiled, not headers, so without them we don't get the whole picture.
You should've posted an actual error, not just your impression of it. With your description we can't even be sure if it's compiler error or linker error.
Nevertheless, I'll propose some possible solutions for your problem.
Try to specify namespace in call to the func:
inline int callfunc(int a){ return abc::func(a); }
You really shouldn't define non-inline functions in headers, you'll get linker errors if you include your headers in more than one .cpp file.So you should keep definitions in .cpp and only declarations in .h files like it was meant to be.
I'm using multiple C++ files in one project for the first time. Both have need to include a protected (#ifndef) header file. However, when I do that, I get a multiple definition error.
What I have is two one .cpp file that calls the header directly, and one indirectly (Another include includes it) and then two other header files that include it.
So what do I need to do to get rid of the error?
ERROR:
obj\Debug\main.o||In function Z14sortLibQtyTest4BookS_':|
[PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'
CODE:
bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }
It should be mentioned that this isn't the only function giving me problems, probably more than ten are, and some aren't so short and sweet. Also, the functions are needed in multiple files.
You have two options to solve this multiple definition problem: Mark the method inline, or put the definition in a .cpp file.
1) Mark the method inline:
// Foo.h
inline bool foo(int i) { return i = 42; }
2) Put the definition in a .cpp file:
// Foo.h
inline bool foo(int i); // declaration
// Foo.cpp
bool foo(int i) { return i = 42; } // definition
Whether the method is actually inlined by the compiler in the first case is irrelevant here: inline allows you to define a non-member function in a header file without breaking the one definition rule.
The ".cpp" and ".h" suffixes are largely a matter of convention. As far as the compiler is concerned, where a line of code came from is irrelevant. When you #include that function into your .cpp files, you are implementing that function in that .cpp file.
So when the compiler is done and it asks the linker to knit together the code from your two cpp files, it finds a conflict: two functions with the same name and fingerprint (arguments and return). This is an error.
You need to either:
a. Put the implementation in one source file, and just leave a prototype declaration in the header
// .h
extern bool sortLibQtyTest(Book a, Book b);
// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }
b. Mark the function as inline: when you call the function, the compiler will insert copies of the function body as needed which can be wasteful, but often times the compiler can figure out the efficient thing to do.
inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
c. Mark the function as "static" which tells the compiler to create a copy of the function for every source file that includes it, but not to expose it to the linker. If some source files include the header without using the function, the compiler has to detect this and remove it - which not all compilers/optimization levels do, so it can be doubly wasteful.
static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }
d. Avoid the downsides of c, mark it static inline
static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
If the Line you quoted after "CODE" is in a header file you can either:
add inline to the definition or
remove the function body from the header and put it into 1 (and only 1) of your source files.
So, someone came to me with a project that failed linking with the error LNK2005: symbol already defined in object (using Visual Studio 2010). In this case, I know what is wrong (and hence could point them to the correct solution), but I don't know why this is wrong on a level to give a good explanation about it (to prevent it happening again).
// something.h
#ifndef _SOMETHING_H
#define _SOMETHING_H
int myCoolFunction();
int myAwesomeFunction() // Note implementing function in header
{
return 3;
}
#endif
-
// something.cpp
#include "something.h"
int myCoolFunction()
{
return 4;
}
-
// main.cpp
#include <iostream>
#include "something.h"
int main()
{
std::cout << myAwesomeFunction() << std::endl;
}
This fails linking, and is fixed by putting myAwesomeFunction() into the .cpp and leaving a declaration in the .h.
My understanding of how the linker works comes pretty much from here. To my understanding, we are providing a symbol that is required in one place.
I looked up the MSDN article on LNK2005, which matches how I expect linkers to behave (provide a symbol more than once -> linker is confused), but doesn't seem to cover this case (which means I'm not understanding something obvious about linking).
Google and StackOverflow yield issues with people not including an #ifndef or #pragma once (which leads to multiple declarations of provided symbols)
A related question I found on this site has the same problem, but the answer doesn't explain why we're getting this problem adequately to my level of understanding.
I have a problem, I know the solution, but I don't know why my solution works
In a typical C++ project, you compile each of the implementation (or .cpp) files separately - you generally never pass a header (or .h) file to the compiler directly. After all preprocessing and inclusions are performed, each of these files becomes a translation unit. So in the example you've given, there are two translation units that look like this:
main.cpp translation unit:
// Contents of <iostream> header here
int myCoolFunction();
int myAwesomeFunction() // Note implementing function in header
{
return 3;
}
int main()
{
std::cout << myAwesomeFunction() << std::endl;
}
something.cpp translation unit:
int myCoolFunction();
int myAwesomeFunction() // Note implementing function in header
{
return 3;
}
int myCoolFunction()
{
return 4;
}
Notice that both of these translation units contain duplicate content because they both included something.h. As you can see, only one of the above translation units contains a definition of myCoolFunction. That's good! However, they both contain a definition of myAwesomeFunction. That's bad!
After the translation units are compiled separately, they are then linked to form the final program. There are certain rules about multiple declarations across translation units. One of those rules is (§3.2/4):
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
You have more than one definition of myAwesomeFunction across your program and so you are breaking the rules. That's why your code doesn't link correctly.
You can think of it from the linker's perspective. After these two translation units are compiled, you have two object files. The linker's job is to connect the object files together to form the final executable. So it sees the call to myAwesomeFunction in main and tries to find a corresponding function definition in one of the object files. However, there are two definitions. The linker doesn't know which one to use so it just gives up.
Now let's see what the translation units look like if you define myAwesomeFunction in something.cpp:
Fixed main.cpp translation unit:
// Contents of <iostream> header here
int myCoolFunction();
int myAwesomeFunction();
int main()
{
std::cout << myAwesomeFunction() << std::endl;
}
Fixed something.cpp translation unit:
int myCoolFunction();
int myAwesomeFunction();
int myCoolFunction()
{
return 4;
}
int myAwesomeFunction()
{
return 3;
}
Now it's perfect. There is only one definition of myAwesomeFunction across the whole program now. When the linker sees the call to myAwesomeFunction in main, it knows exactly which function definition it should link it to.
The linker is merely letting you know that you broke the one definition rule. This is a basic, well-documented rule of C++ - it isn't solved by using include guards or #pragma once directives, but, in case of a free function, by marking it inline or moving the implementation to a source file.
When a non-inline method is implemented in a header, all translation units that include that header will define it. When the corresponding .obj files are linked together, the linker detects the same symbol is exported (and defined) multiple times, and complains.
Moving the implementation to a cpp file effectively transforms your initial definition into a declaration.
myAwesomeFunction is defined in two source files: something.cpp and main.cpp. Move its implementation to one of source files, or declare this function as static.
I have a file iforce2d_topdown_car.h in a demo project with an include guard like so:
#ifndef IFORCE2D_TOPDOWN_CAR_H
#define IFORCE2D_TOPDOWN_CAR_H
... source code ...
#endif
This is included in HelloWorldLayer.h, which is then included in two other files (this is all obj-c except for the iforce2d header). Everything compiles fine, but any errors I get are displayed 3 times. This annoys me, and I wonder if its symptomatic of a larger issue.
Is this expected behavior? It seems to me that if a preprocessor var is defined, then it will stay defined and next time it is included it will not be compiled. It seems that is not the case here, but I do not know why.
The TDCar(b2World *) is an inline member function because it is defined inside its class definition. That means the compiler instantiates the function and emits the corresponding warnings in every translation unit that calls this function.
Let's imagine you have the following A.h:
class A {
public:
int f(int i);
};
and A.cpp
int A::f(int i) {
int j = i;
return i + 1;
}
The compiler will compile the function A::f(int i) once and export it so every call to that function will link to the exported symbol. Therefore, the warning for the unused variable j will be emitted once: when A.cpp is compiled.
But if you write the following A.h:
class A {
public:
int f(int i) {
int j = i;
return i + 1;
}
};
Then the compiler will copy the code from the function definition directly into the source code file that calls the function. If you use that function in 3 different files, the function is compiled thrice and the warning is emitted thrice.
As each file is compiled individually, the compiler cannot know the warning was already emitted for another file.
Xcode should be clever enough to recognize the three warnings as being the same and aggregate them so you only get one warning. Unfortunately, Xcode isn't that clever.
I have 2 files, A.cpp and B.cpp, in a Win32 console application.
Both 2 files contain only the following 2 lines of code:
#include "stdafx.h"
int k;
When compiling it produces the error
Error 1 error LNK2005: "int k" (?a##3HA) already defined in A.obj
I don't understand what is happening.
Can someone please explain this to me?
Why this error?
You broke the one definition rule and hence the linking error.
Suggested Solutions:
If you need the same named variable in the two cpp files then You need to use Nameless namespace(Anonymous Namespace) to avoid the error.
namespace
{
int k;
}
If you need to share the same variable across multiple files then you need to use extern.
A.h
extern int k;
A.cpp
#include "A.h"
int k = 0;
B.cpp
#include "A.h"
//Use `k` anywhere in the file
In the Project’s Settings, add /FORCE:MULTIPLE to the Linker’s Command Line options.
From MSDN: "Use /FORCE:MULTIPLE to create an output file whether or not LINK finds more than one definition for a symbol."
If you want both to reference the same variable, one of them should have int k;, and the other should have extern int k;
For this situation, you typically put the definition (int k;) in one .cpp file, and put the declaration (extern int k;) in a header, to be included wherever you need access to that variable.
If you want each k to be a separate variable that just happen to have the same name, you can either mark them as static, like: static int k; (in all files, or at least all but one file). Alternatively, you can us an anonymous namespace:
namespace {
int k;
};
Again, in all but at most one of the files.
In C, the compiler generally isn't quite so picky about this. Specifically, C has a concept of a "tentative definition", so if you have something like int k; twice (in either the same or separate source files) each will be treated as a tentative definition, and there won't be a conflict between them. This can be a bit confusing, however, because you still can't have two definitions that both include initializers--a definition with an initializer is always a full definition, not a tentative definition. In other words, int k = 1; appearing twice would be an error, but int k; in one place and int k = 1; in another would not. In this case, the int k; would be treated as a tentative definition and the int k = 1; as a definition (and both refer to the same variable).
Assuming you want 'k' to be a different value in different .cpp files (hence declaring it twice), try changing both files to
namespace {
int k;
}
This guarantees that the name 'k' uniquely identifies 'k' across translation units. The old version static int k; is deprecated.
If you want them to point to the same value, change one to extern int k;.
Both files define variable k as an integer (int).
As a result, the linker sees two variables with the same name, and is unsure which one it should use if you ever refer to k.
To fix this, change one of the declarations to:
extern int k;
That means: "k is an integer, declared here, but defined externally (ie. the other file)."
Now there is only one variable k, that can be properly referred to by two different files.
And if you want these translation units to share this variable, define int k; in A.cpp and put extern int k; in B.cpp.
Presence of int k; in the header file causes symbol k to be defined within each translation unit this header is included to while linker expects it to be defined only once (aka One Definition Rule Violation).
While suggestion involving extern are not wrong, extern is a C-ism and should not be used.
Pre C++17 solution that would allow variable in header file to be defined in multiple translation units without causing ODR violation would be conversion to template:
template<typename x_Dummy = void> class
t_HeaderVariableHolder
{
public: static int s_k;
};
template<typename x_Dummy> int t_HeaderVariableHolder<x_Dummy>::s_k{};
// Getter is necessary to decouple variable storage implementation details from access to it.
inline int & Get_K() noexcept
{
return t_HeaderVariableHolder<>::s_k;
}
With C++17 things become much simpler as it allows inline variables:
inline int g_k{};
// Getter is necessary to decouple variable storage implementation details from access to it.
inline int & Get_K() noexcept
{
return g_k;
}
The linker tells you that you have the variable k defined multiple times. Indeed, you have a definition in A.cpp and another in B.cpp. Both compilation units produce a corresponding object file that the linker uses to create your program. The problem is that in your case the linker does not know whic definition of k to use. In C++ you can have only one defintion of the same construct (variable, type, function).
To fix it, you will have to decide what your goal is
If you want to have two variables, both named k, you can use an anonymous namespace in both .cpp files, then refer to k as you are doing now:
.
namespace {
int k;
}
You can rename one of the ks to something else, thus avoiding the duplicate defintion.
If you want to have only once definition of k and use that in both .cpp files, you need to declare in one as extern int k;, and leave it as it is in the other. This will tell the linker to use the one definition (the unchanged version) in both cases -- extern implies that the variable is defined in another compilation unit.