error LNK2005...already defined 

While building my code in VS2008 I am getting a build error:

error LNK2005...already defined in ....
1>Linking...
1>Main.obj : error LNK2005: "unsigned char * X1" (?X1@@3PAEA) already defined in BC.obj
1>Main.obj : error LNK2005: "char * X2" (?X2@@3PADA) already defined in BC.obj
1>Rs.obj : error LNK2005: "unsigned char * X1" (?X1@@3PAEA) already defined in BC.obj
1>Rs.obj : error LNK2005: "char * X2" (?X2@@3PADA) already defined in BC.obj

In my project I have three .h files:

1) Common_Definitions.h

    unsigned char X1[16];
    char X2[4];                               

    struct xyz
    {
       UINT32 X3;                                   
       unsigned int X4[4];
       long X5;                                  
       int X6;                                    
       int X7;                                        
    };

2) BC.h
3) RS.h

I have three .cpp files
1) Main.cpp
2) BC.cpp
3) RS.cpp

In Common_Definitions.h I have definitions/declarations which I want to be available in entire project, While BC.h and RS.h has corncenred variables.
I have included Common_Definitions.h in BC.h and RS.h.

#ifndef Common_Definitions_h
#define Common_Definitions_h
#include "Common_Definitions.h"
#endif 

I have included BC.h and RS.h in their corresponding .cpp files.
I have included BC.h and RS.h also in Main.cpp

Now while building I get the linker error KNK2005.
How to resolve it?

Earlier when I had included Common_Definitions.h in BC.h and RS.h directly without ifndef.

#include "Common_Definitions.h"

then it was giving compilation error:

1>d:\...\common_deFINITIONS.h(18) : error C2086: 'unsigned char X1[16]' : redefinition
1>        d:\...\common_deFINITIONS.h(18) : see declaration of 'X1'
1>d:\...\common_deFINITIONS.h(19) : error C2086: 'char X2[4]' : redefinition
1>        d:\...\common_deFINITIONS.h(19) : see declaration of 'X2'
1>dd:\...\common_deFINITIONS.h(22) : error C2011: 'XYZ' : 'struct' type redefinition
1>        d:\...\common_deFINITIONS.h(22) : see declaration of 'XYZ'

So to resolve that I have included Common_Definitions.h in BC.h and RS.h using ifndef.

#ifndef Common_Definitions_h
#define Common_Definitions_h
#include "Common_Definitions.h"
#endif 

But this is leading to linker error.

Please let me know how to resolve this compiler and linker issue?

Edited 3 Years Ago by mike_2000_17: Fixed formatting

You can not declare objects in a header file without the extern keyword. When you do it without that you will get the results you have because the objects will be defined in every *.cpp file in which the header file is included. Use extern in header files. Then in one, and only one *.c or *.cpp file declare them again but without extern.

You can not declare objects in a header file without the extern keyword. When you do it without that you will get the results you have because the objects will be defined in every *.cpp file in which the header file is included. Use extern in header files. Then in one, and only one *.c or *.cpp file declare them again but without extern.

thanks Ancient Dragon for the reply.
I tried it and it worked fine.
But I am not using any objects.
Its a .cpp file but all code is in C.
So the extern rule will be applicable to these too?

I have included Common_Definitions.h in BC.h and RS.h.
#ifndef Common_Definitions_h
#define Common_Definitions_h
#include "Common_Definitions.h"
#endif

Inclusion protection preprocessor symbols like this are good, but they should go inside the file they are protecting not round every place it is included. Common_Definitions_h should have the structure

#ifndef Common_Definitions_h
#define Common_Definitions_h

... declarations and inclusion of other files here

#endif

and then you just included it like this

#include "Common_Definitions.h"

Your link errors are a rresult of the contents of Common_Definitions.h

1) Common_Definitions.h
unsigned char X1[16];
char X2[4];

struct xyz
{
UINT32 X3;
unsigned int X4[4];
long X5;
int X6;
int X7;
};

You are defining X1 and X2 when you should be declaring them. A definition basically causes the compiler to create an object, in this case the are variables so it reserves data for them. A declaration informas the compiler that the object exists somewhere and that it doesn't need to create it it can just use it.

When you define data in a header file and that header is included into multiple C files every object file produced by the compiler has space reserved for that variable. Then when the linker trys to link all the object files it finds that the variable is defined in multiple locations and since it has no way of telling what to do sensibly in that situartion it stops with a "multiple definition" or "already defined" error.

A data declaration looks like this extern unsigned char X1[16]; that is what should be in your header file, then in 1 cpp file you declare the data with extern unsigned char X1[16]; .

That way all cpp files can see the declaration and use the data but it is only defined in one file so there is only one definition of the data and the linker doesn't get confused.

BTW you should avoid using global data if at all possible, it leads to bugs and maintenance problems.

But I am not using any objects.

It's an ambiguous use of the term object (that we all do).

In an object orientated programming sense an object is an instantiation of a class. However in the context of any executable code an object is any thing that takes up space in memory such as a char array.

Comments
good point.

Thanks Banfa for the error.
Presently I have just declared it as extern in .h file and not redeclraed it again in any .cpp file. But the error has gone. I guess it may be because while including the contents of the file in #include this redeclaration comes in autonmatically and so we do not need to redeclare it again it in .cpp file.

Will you please clarify the reason of the compilation error too?

This one?

1>d:\...\common_deFINITIONS.h(18) : error C2086: 'unsigned char X1[16]' : redefinition

This happens when the compiler sees 2 definitions of the same object (not the OOP type) such as when you define something in a header file that doesn't use multiple inclusion protection via #defines and then included it multiple times directly or indirectly into a single cpp file.

This one?

1>d:\...\common_deFINITIONS.h(18) : error C2086: 'unsigned char X1[16]' : redefinition

This happens when the compiler sees 2 definitions of the same object (not the OOP type) such as when you define something in a header file that doesn't use multiple inclusion protection via #defines and then included it multiple times directly or indirectly into a single cpp file.

ok thanks
this clarifies it all.
Also presently I did not declare the variables as extern in the header files, But I included the declaration of header files as:
Declaration for common_definitions.h, bc.h and rs.h is now changed as:
#ifndef bc_h
#defibe bc_h
-----declaration of bc.h
#endif

#ifndef rs_h
#define rs_h
-----declaration of rs.h
#endif

This also resolved the issue.

This article has been dead for over six months. Start a new discussion instead.