error LNK2005, already defined? - c++

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.

Related

How do I fix the error LNK2005 struct node * root" (?root##3PAUnode##A) already defined in AVL.obj? [duplicate]

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.

Defined multiple times for the inline function, how possible?

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).

c++ extern constant int for array size

I have the following three files in my code (with most of the code removed. This is just to isolate the issue).
global.h:
//global.h
#ifndef GLOBAL_H
#define GLOBAL_H
extern const int ARRAYSIZEX;
extern const int ARRAYSIZEY;
extern const int ARRAYSIZEZ;
#endif //GLOBAL_H
global.cpp:
//global.cpp
#include "global.h"
const int ARRAYSIZEX = 5;
const int ARRAYSIZEY = 2;
const int ARRAYSIZEZ = 4;
main:
//main
#include "global.h"
using namespace std;
someType mySomeTypeArray[ARRAYSIZEX][ARRAYSIZEY][ARRAYSIZEZ];
int main(int argc, char **argv)
{
//...
}
Compiling gives me three errors at the declaration of mySomeTypeArray.
error: array bound is not an integer constant before ']' token
I want to keep my global variable and array size definitions in global.h/cpp for this application, just for organization, so that all my configuration parameters are in one place. What's the proper way to achieve what I'm trying to do?
Thanks
Your declaration is failing because array sizes need to be evaluated at compile-time and your encapsulation scheme is actually hiding the values from the compiler. This is true because compilers work on individual translation units. While compiling main.cpp your compiler sees only extern const int ARRAYSIZEX thanks to the include statement, but not the value which is visible in a separate translation unit so it can't figure out the memory layout.
While const variables can used as array sizes in some contexts, the language provides the more appropriate constexpr qualifier which comes with a set of restrictions that enforce its compile-time evaluation and suitability for array sizes. I recommend always using it when appropriate because it will point you to the error in situations such as this. In this case, you would get a compiler error because an extern constexpr declaration is ill-formed which hints at the proper solution: to hold the values for compile-time constants directly inside the header file.
global.h
constexpr int ARRAYSIZEX = ...;
constexpr int ARRAYSIZEY = ...;
constexpr int ARRAYSIZEZ = ...;
main.cpp
#include "global.h"
someType mySomeTypeArray[ARRAYSIZEX][ARRAYSIZEY][ARRAYSIZEZ];
The problem here is extern int x means "x is defined in another file, but don't worry about the particulars, all you need to know is it's an int". This is normally good enough, except when the compiler needs to know right there and then what x is.
Since that's defined in a whole other file it can't. That file must be compiled before it knows, and the result of that compilation, due to the way C++ works, can't impact the compilation of this file.
You'll need to declare that as a const int in a header if you want to share those values. extern int won't cut it.
Although this is a trivial example, there's really no reason to go down the extern road at all. Just define the values in the header file as regular const int.
Array size must be specified by an integer constant expression. A const int object can be used in an integer constant expression if and only if it declared with an initializer and that initializer is also an integer constant expression. Your ARRAYSIZE... variables do not satisfy that requirement. In main they are declared without an initializer. You cannot use ARRAYSIZE... variables as array sizes in main.
Unless you have a specific requirement to give these variables external linkage, simply declare (and define) them in the header as
const int ARRAYSIZEX = 5;
const int ARRAYSIZEY = 2;
const int ARRAYSIZEZ = 4;
These object will have internal linkage though, which is different from what your original variant attempts to do.
If really want to give them external linkage, declare them as inline extern const in the header
inline extern const int ARRAYSIZEX = 5;
inline extern const int ARRAYSIZEY = 2;
inline extern const int ARRAYSIZEZ = 4;
Since inline by itself prevents const from imposing internal linkage, extern is entirely optional in these declarations. And since inline const combination can be replaced with constexpr (as #M.M noted in the comments), you can achieve the same effect with just
constexpr int ARRAYSIZEX = 5;
constexpr int ARRAYSIZEY = 2;
constexpr int ARRAYSIZEZ = 4;
The problem here is that ARRAYSIZEX, ARRAYSIZEY and ARRAYSIZEZ are not the compile time constants. They are constants - so their values can't be changed but their values are not known to compiler.
In C++ the compilation process consists of 3 basic steps.
Preprocessing of all source files done by preprocessor.
Compilation for every translation unit (.cpp file) done by compiler. For every translation unit compiler creates an object file.
Linking of all object files done by linker. The output is an executable file.
In C++ the keyword extern for compiler means that the variable is 'somewhere' defined. The compiler doesn't know the variable's real address but by placing keyword extern it's assured that the variable really exists and the linker will be able to find its address by its name when creating the executable file.
The problem here is that compiler in step 2 wants to create the object file but it doesn't known how big the array is going to be because it doesn't know the value of these constants. Yes, linker in step 3 will finally find them when putting together all object files but it's too late for compiler. So it generates that error.
The solution is simple. Use already mentioned constexpr keyword and initialize all variables with initializers. The keyword constexpr marks compile time constants - constants that have to be initialized in initializers and are known to compiler.

include header file error: multiple definition

I have a very simple file system in a program.
There is :main.cpp which include worker.h, worker.h and worker.cpp which include worker.h
worker.h has the Header guard and has some variables declared which are required by both main.cpp and worker.cpp and it has some function declarations.
#ifndef __WORKER_H_INCLUDED__
#define __WORKER_H_INCLUDED__
bool x;
int y;
void somefunction( int w, int e );
#endif
Going through some other threads and google results, I understood that the Header guard protects you from multiple inclusions in a single source file, not from multiple source files.
So I can expect linker errors.
My question is
Why there are multiple definition errors for only variables and not for functions ? As far as my understanding goes both of those are only declared and not defined in the header file worker.h
How can I make the a variable available to both main.cpp and worker.cpp without the multiple definition linker error ?
Why there are multiple definition errors for only variables and not for functions ? As far as my understanding goes both of those are only declared and not defined in the header file worker.h
Because you defined the variables. This way they are only declared :
extern bool x;
extern int y;
But you have to define them in a cpp file. :
bool x = true;
int y = 42;
An updated answer for c++17. With the introduction of inline variables, one no longer needs to worry about the exact translation unit where non-const namespace scoped variables need to be placed. Putting aside the discussion about use of global variables in general, another way to fix the OP in modern C++ is to declare the variables as follows:
inline bool x; // Can add an initializer here too
inline int y;
So long as this is in a header and all TU's see the same exact definition, the implementation will resolve it and make sure those TU's all refer to the exact same unique object.

Can I include global static member?

There are few global variables which are static in one of the header files. I see these variables are used in the associated .cc files. So, looks like this has no issues.
My questions are:
Whats the difference between including a global variable vs static global variable ?
I know static global doesnt have visibility outside its file. But dont know how this would work when it comes as part of a .h which is #included.
I wrote a sample program, and tried the same thing. But, I get compilation error the moment I make the variable static. When it is just global, it is fine.
So, is there something which I am missing on a regular g++ build ? (Please note, the initial case was on our official code base which has enough makefiles, .h files and all).
Thanks for the help !
Here is my sample program :
.h file:
#include <iostream>
typedef unsigned int uint;
static const int appk=189;
class abc1
{
public:
abc1(int x);
virtual void printVal();
};
.cc file:
#include "abc1.h"
extern int appk;
abc1::abc1(int x)
{
}
void abc1::printVal()
{
printf("abc1 print: %d\n", appk);
}
(1) If you put a global variable in a .h file and include it in various .cpp/.cc files then it will be defined multiple times for every file. So you are most like to get a linker error.
To overcome that, mostly you are likely to use extern keyword:
// myfile.h
extern int i;
and define that in only one translation unit:
// somefile.cc
int i;
(2) If you put a static global in a .h file and include it, then you will not get any error, because for every different translation unit, there will be a different copy for that static global variable.
// myfile.h
static int i; // creates a unique and unrelated copy in all .cc file where included
However, such usage is deprecated; instead of that it's better to use unnamed namespace:
namespace {
int i;
}
From your question, I don't see that you should get any linker error for static global.
Hard to tell your compilation error without code, but if you have a header that declares a static global, then you just create that global variable independently and separately in each translation unit that includes the header.
Example:
header.h:
#ifndef H_XXX
#define H_XXX
static int a;
#endif
file1.cpp:
#include "header.h"
// now have access to a variable called "a"
file2.cpp:
#include "header.h"
// now also have access to some "a"
The two files both have access to a global variable called a, but each file has its own separate copy, private to its translation unit, which is not visible outside.
For a practical example, I think cout is declared as a static global, so everyone who uses <iostream> gets their own copy.
static variable has internal-linkage. What it means is that if you have a static variable a in x.h and you include x.h in two files say m.cpp and n.pp then each of these two files gets its own copy of a which means if you change its value in m.cpp, then n.cpp is not going to see that change, because there exists two variables with same name in each translation unit (.cpp). And they're independent of each other.
But if a is not static, then including x.h in more than one files, you will get multiple-definition error, because each inclusion of x.h will try to define a, but since a is not static; it has external linkage now, which means if its defined in m.cpp, then you will get error when including x.h in n.cpp (or vice-versa). In this case, you've to write x.h as:
//x.h
extern int a;
And then define a in exactly one .cpp file, either m.cpp or n.cpp, but not both. Say its m.cpp.
//m.cpp
#include "x.h"
int a =10;
And you're done. Now you can include x.h in as many .cpp file as you want, and can access a, modify its value, do whatever you want. Any change to it, will be seen by all .cpp files now.