Why "int i" has multiple definitions? - c++

I have two files as below:
Test1.h
#ifndef TEST_H
#define TEST_H
int i = 10;
#endif
Test2.cpp
#include <iostream>
#include "Test1.h"
int main()
{
std::cout << i << std::endl;
}
I know I can solve this by using extern or const in Test1.h.
But my question is that "I don't understand the error".
error LNK2005: "int i" (?i##3HA) already defined in Test1.obj
error LNK1169: one or more multiply defined symbols found
How can int i have multiple definitions?
The header file has include guards.
When I include the header file it should mean that everything gets copied in Test2.cppand it should become:
Test2.cpp
#include <iostream>
int i = 10
int main()
{
std::cout << i << std::endl;
}
And header file should become irrelevant at this point after everything being included.
My other question is if I declare int i with extern in header file and include it in .cpp, then would it be an example of external linkage? Because generally I have seen external linkage between two .c or .cpp as in here but if you explicitly include the file is it still regarded as i having external linkage?

Each compilation unit (a .cpp file) produces its own set of symbols individually which are then linked together by the linker.
A header file "becomes" part of the compilation unit it is included in, which compile to an object file (.obj in Windows, .o in Unix systems)
Therefore it is like you have defined a global 'i' in each compilation unit.
The correct solution (as you know, if you have to have a global) is to declare it as "extern" in the header then have one compilation unit actually define it.
Include guards only prevent the same header being included twice in the same compilation unit, which can happen if I include and and one of those includes the other.

How can int i have multiple definitions?
The file that has the definition was included in multiple translation units (cpp file). One unit was compiled into the object file Test1.obj. The source of the other unit is shown in your answer (Test2.cpp). The error is shown when you try to link the object files together.
The header file has include guards.
That prevents the contents of the file from being repeated within a single translation unit. It makes no difference to separate units.
My other question is if I declare int i with extern in header file and include it in .cpp, then would it be an example of external linkage?
extern makes the linkage external explicitly. But even without extern, variables declared in the namespace scope have implicit external linkage by default (there are exceptions). The difference in this case is that extern variable declarations are not definitions unless there is an initializer.
I can achieve external linkage without including header file i.e. with two .cpp files by making a variable extern in one .cpp and defining it in other and linker finds its definition. But if I have one header file with extern variable and include it in other .cpp does this count as external linkage?
It does not matter how the extern declaration ends up in the cpp file. Whether it was included from a header or not, it declares a variable with external linkage.

Probably you are trying to create the executable file from two unit of translations.
Your error shows that the object have been defined in Test1.obj. Probably, your program is Test1.obj+Test2.obj, and both files include the same definition, which has external linkage.

Do you have other Test1.cpp in your project that also include the Test1.h ?
If not, do you do any config to your compiler so it also build the .h files to object files ?
The reason can just be the answer of one of two questions above.

When I include the header file it should mean that everything gets copied in Test2.cpp and it should become:
Yes and then you do the exact same thing in Test1.cpp (which you didn't show us).
Hence, multiple definitions.

Related

Static functions can't be called from any other file vs static function created in header file can be called by other files

Can anyone tell me how a static function created in header file can be invoked in other files, though static function which is not created in header file can't be invoked in other files. What exactly happens when we declare static functions in header file vs other cpp/c files.
The "file" is a more or less meaningless concept in C and C++ - what matters is the "translation unit".
Somewhat simplified, when you compile one source file, that's one translation unit.
The #include mechanism is extremely simple - it literally just includes the contents of a file at that point.
And static makes a name local to the translation unit; it can't be seen anywhere else.
So, say you have a header "H.h":
static something X;
and two source files,
A.cpp:
#include "H.h"
and B.cpp:
#include "H.h"
then after preprocessing, this is what the compiler sees:
A.cpp:
static something X;
and B.cpp:
static something X;
In other words, you have two somethings called "X", completely independent of each other, and neither translation unit can access the other's.
(This is a frequent source of bugs that can be very hard to find, in particular if the intent is to have a globally mutable variable. Don't make things static in headers.)
If you define static function in a header file it will be be visible in any source file which includes this header file. You will have as many copies of the static function as you have source files that include it. It will increase the program size. I would suggest only defining static inline functions in the header files.
It is a common misunderstanding in C. Beginner programmers think that the header file is a "library" but in the fact "#include" only textually replaces #include <file.h> with the context of file.h creating one source file which is compiled by the compiler.
Example:
https://godbolt.org/z/Y5s9fecP6

#pragma once or include guards not working on extern funcs

I'm experiencing a very strange (and annoying) linker error on my project.
Say for example I have the file KernelExports.h:
#pragma once
extern "C"
{
DWORD* KeTimeStampBundle;
DWORD KeGetCurrentProcessType();
//etc...
}
I then #include this in my stdafx.h and then add #include "stdafx.h" all all my *.cpp files. The problem is that now whenever I build I get a stream of linker errors: LNK2005: KeTimeStampBundle already defined in stdafx.obj. This should not be happening since the header file is only included in one file and is protected with include guards. The errors stop once I comment out the whole extern "C" block so I know that is what is causing the issue.
What's even stranger is when I add all these source files to a new project it builds without any problems. I don't see what the issue is here, can anyone enlighten me?
My IDE is Visual Studio 2008.
DWORD* KeTimeStampBundle;
This does not declare a function. It declares and defines an object of type DWORD* named KeTimeStampBundle. If you include this header file in multiple source files, you will have multiple definitions of this object (one from each source file in which the header is included).
Include guards and #pragma once ensure that something is only defined once in a given translation unit (source file). They have no effect on how things are defined across multiple translation units.
#pragma once doesn't keep your file from being included multiple times in the project, it keeps it from being included multiple times in the same file. So a.cpp and b.cpp can include the file once, and that defines KeTimeStampBundle twice.
To fix this, put the definition of KeTimeStampBundle and KeGetCurrentProcessType, etc. into a .cpp file and put extern DWORD* KeTimeStampBundle, etc in the header.
Note that this only applies to definitions, not declarations. extern ... and function prototypes are declarations, so they can be done multiple times, but definitions can only occur once in the entire project, accross all .cpp files.

One or more multiply defined symbols found

DebugUtil.h
#ifndef DEBUG_UTIL_H
#define DEBUG_UTIL_H
#include <windows.h>
int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
#endif
When I try to run this I get this error:
Terrain.obj : error LNK2005: "int
__cdecl DebugMessage(char const *)" (?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
Renderer.obj : error LNK2005: "int
__cdecl DebugMessage(char const *)" (?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
test.obj : error LNK2005: "int __cdecl
DebugMessage(char const *)"
(?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
C:\Users\Tiago\Desktop\Loodus
Engine\Debug\Loodus Engine.exe : fatal
error LNK1169: one or more multiply
defined symbols found
But why does this happen? I have #ifndef #define and #endif in the header so multiple definitions shouldn't happen
Put the definition (body) in a cpp file and leave only the declaration in a h file. Include guards operate only within one translation unit (aka source file), not across all your program.
The One Definition Rule of the C++ standard states that there shall appear exactly one definition of each non-inline function that is used in the program. So, another alternative would be to make your function inline.
Make the function inline or declare the function in a header file and define it in a cpp file.
inline int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
EDIT:
As a comment by Tomalak Geret'kal suggests, it's better to use my latter suggestions than my former and move the function's declaration to a cpp file.
(Assuming the posted code is a header, included from multiple .cpp files)
Header guards do not protect you from link-time multiple definitions. Regardless that you have ensured the header will only appear once per Translation Unit, if you have more than one Translation Unit then that's still multiple definitions.
Write definitions in source files, and only declarations in headers.
The only exceptions are inline functions, functions defined within a class definition (though this is not recommended!) and function templates.
This function is included into every translation unit and as a result you get multiple definitions of it - each .obj file contains its own copy. When it's time to link them all together the linker rightfully shows the above error.
You can do a few things:
Move the definition to a .cpp file and keep only the declaration in the header.
Use an anonymous namespace around the function in your header file (but realize it's a hack - you will still have multiple definitions, just no name collision).
Mark it as inline (although it might not always work - only if the compiler actually chooses to inline it). That's also a hack for the same reason as above.
That only prevents multiple inclusions in the same source file; multiple source files #includeing it will still generate multiple definitions of DebugMessage(). In general, you should either not place functions in header files at all or make them static (and usually inline, since otherwise it doesn't usually make sense to have multiple static definitions of the same function).
100% Certain you correctly included Guards but still getting redefinition error?
For Visual Studio:
I was really frustrated because I was correctly included guards,
only to find out the problem was visual studio. If you have added the file
to your project, the compiler will add the file twice even if you have
include guards around your implementation file and header file.
If you don't use visual studio exclusively, and say... use code::blocks sometimes, you might want to only #include the file when you detect the absence of the visual studio environment.
DebugUtil.h :
----------------------
#ifndef _WIN32
#include "DebugUtil.c"
#endif
----------------------
If you are okay with including stdio.h,
you can be a little less hackish about it:
DebugUtil.h :
----------------------
#include <stdio.h>
#ifdef _MSC_VER
#include "DebugUtil.c"
#endif
----------------------
Reference:
Predefined Macros, Visual Studio:
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
Move the definition to a .cpp file.
Declare your functions in C++ files. Since you defined your function in the header file, and that header file is included from multiple source files, it gets defined for each source file that includes it. That's why it's reported as being defined in multiple places.
Alternatively, you could make it inline so that the code is inserted wherever it's used instead of being defined as a separate function each time.
It looks like you are including DebugUtil.h in more than one translation unit, then linking those objects together. However, DebugUtil.h provides a definition for the DebugMessage function, so that definition exists in all of the translation units that incorporated the header. As a result, when you link the objects, the linker rightly complains that the symbol is multiply defined.
Change DebugUtil.h so that it declares DebugMessage via a prototype, but does not provide a definition, and place the definition of DebugMessage in a .c file which you will compile and link with your other objects.

Multi Including a .h File

In an .h file, I am declaring a global variable as:
#pragma data_seg(".shared")
#ifndef DEF_VARX
#define DEF_VARX
int VARX=0;
#endif /*DEF_VARX*/
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
However if I include this file in multiple cpp files, when I try to compile, I get " error LNK2005: "int VARX" (?VARX##3HA) already defined in Dll.obj" error. If I include in only one cpp file, no problem is encountered.
Isn't #IFNDEF.... check enough for preventing this? Am I missin something?
The reason of this behavior is, that you compile the line
int VARX=0;
into each .obj file. Thats OK for compiling, but upon linking the symbol becomes multiply defined, which is illegal. Using
extern int VARX;
in the header file, and
int VARX=0;
in one (and only one) source file resolves this problem.
I think you're supposed to forward declare the variable in the .h and later define it in its shared section in a .cpp, something like:
// in a header file
#pragma once
extern int VARX;
// in a .cpp
#pragma data_seg(".shared")
int VARX=0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
The problem is that is that you prevent multiple inclusion of the file for a given translation unit. (for a given say cpp file)
But if several of your cpp include this VARX.H, then you'll have more than one definition for this variable.
Instead, you should only declare the variable in the .H file, but initialize it to 0 in only one location.
Yes, you're missing the extern keyword.
In your header file, use:
extern int VARX;
In a source file, actually declare space for the variable:
int VARX = 0;
ifdef prevents it for a separe object file. When the header is include in several source (cpp) files, VARX will be dedfined in all of them. Consider declaring it as extern in header file, and initialize in one cpp file.
The problem is you must be including the file in multiple compilation units. Let's say you have a.cpp and b.cpp. Both include your header file. So the compiler will compile (and pre-process) separately, so for both files, DEF_VARX is not yet defined. When you go to link the to object files together, the linker notices that there is a name collision.
As others have suggested, the solution would be to declare it 'extern', then place the actual value in a cpp file, so it only is compiled once, and linked to everything without name collisions.

What is the conventions for headers and cpp files in C++?

In C++, what is the convention for including headers for class files in the "main" file. e.g.
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
#include "myclass.cpp"
etc..
Is this relatively standard?
You don't include the .cpp file, only the .h file. The function definitions in the .cpp will be compiled to .obj files, which will then be linked into the final binary. If you include the .cpp file in other .cpp files, you will get two different .obj files with the same funciton definition compiled, which will lead to linker error.
See Understanding C Compilers for a lot of good answers to this question.
You can say one .cpp file and all its included headers make up one translation unit. As the name implies, one translation unit is compiled on its own. The result, often called file.o or file.obj, of each translation unit, is then linked together by the linker, fixing up yet unresolved references. So in your case you have
Translation Unit 1 = run.cpp: myclass.h ...
Translation Unit 2 = myclass.cpp: myclass.h ...
You will have your class definition appear in both translation units. But that's OK. It's allowed, as long as both classes are equally defined. But it's not allowed to have the same function appear in the two translation units if the function is not inline. Not inline functions are allowed to be defined only once, in one single translation unit. Then, you have the linker take the result of each translation unit, and bind them together to an executable:
Executable = mystuff: run.o myclass.o ...
usually you compile the .cpp file separately and link the resulting .o with other .o's
So myclass.cpp would include myclass.h and would be compiled as a unit.
You compile cpp files separately. If you include any given cpp file into two or more cpp files yoy might encounter a conflict during linking phase.
You don't include one *.cpp inside another *.cpp. Instead:
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
#include "myclass.h"
MyClass::doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
etc..
Instead of including myclass.cpp inside main.cpp (such that the compiler would see both of them in one pass), you compile myclass.cpp and main.cpp separately, and then let the 'linker' combine them into one executable.