Click here to Skip to main content
15,911,139 members
Please Sign up or sign in to vote.
4.20/5 (3 votes)
See more:
Lets say I have 2 CPP files

MyFile1.cpp
MyFile2.cpp

MyFile1.cpp has

C++
#include <vector>

std::vector<int> obj1;


and MyFile2 has the same code :

XML
#include <vector>

std::vector<int> obj2;


Now I compile these two files separately and get two obj files. MyFile1.obj and MyFile2.obj

Now why don't I get linking error when linking these two files to make and executable.

This is assuming the each file will have an instantiation of
vector<int>
class.

What happens in the background during the linking process in this case.
Posted
Updated 16-Aug-13 0:08am
v4
Comments
Mohibur Rashid 16-Aug-13 5:41am    
linking with what?
Aswin Waiba 16-Aug-13 5:42am    
linking the two files to make an executable.
Maarten Kools 16-Aug-13 6:00am    
You can't have two global variables with the same name. Add the external keyword in front of one of them.
enhzflep 16-Aug-13 7:22am    
I'm not sure I understand why you think there would be a linking error.
You've got two files, each with a uniquely-named variable in it. What problem do you anticipate?
Aswin Waiba 16-Aug-13 8:00am    
Please see below for further clarification

In case you wish to know how a linker works, check out these links:
Beginner's Guide to Linkers[^]
How does the compilation, linking process work?[^]

In case you wish to know why you previously got a linker error, and now you don't.

In the previous iteration of your question you had a global variable with the same name in both files:
C++
std::vector<int> obj;


That results in a linker error. The solution would be to either rename it (but probably not what you want), or to add the external keyword to one of them, like so:
C++
external std::vector<int> obj;


This will not redefine the variable, but will allow you to use it in the other file.

So, obviously, renaming the global variables (as you did in v4 of your question) will not result in a linker error.
 
Share this answer
 
v2
Your question relates to how templated classes are instantiated. There is no conflict because before obj1 and obj2 are created by the compiler the class as such does not exist.


http://msdn.microsoft.com/en-us/library/7y5ca42y.aspx[^]


http://www.learncpp.com/cpp-tutorial/142-function-template-instances/[^]

std::vector is not a class definition but a set of rules for creating a class.
 
Share this answer
 
v4
Maybe your question is related to the methods of the template and not the actual template instances (like obj1 and obj2). All used methods of the template get compiled into the object file of all compilation units that use them. This is not a template related "problem", it is a more general problem related to inline functions and methods residing in public headers visible by two or more compilation units.
Example inline functions/methods in a header:
C++
inline void MyGlobalFunc()
{
}

class MyClass
{
public:
    // This constructor is automatically inline because the body of this function
    // was defined inside the class declaration!
    MyClass()
    {
    }

    // Automatically inline for the same reason as the constructor.
    void Method1()
    {
    }

    // Automatically inline for the same reason as the constructor.
    // This declaration would be the same without the optional inline keyword.
    inline void Method2()
    {
    }

    // See the method definition below.
    void Method3();
    // See the method definition below.
    void Method4();
};

// Not inline!!! Because the method body was specified outside the class body
// without the inline keyword!!! This should be put into a .cpp file!
void MyClass::Method3()
{

}

// Inline because you specified the inline keyword like in case of the global function.
inline void MyClass::Method4()
{

}

The same inline function/method is allowed to be present in many object files and the linker will keep only one of these. There is only one big problem!!! The linker compares the inline methods only by their signature! If you succeed to put two inline methods or functions into two different object files with the same signature but with different implementation then your stuff will link but only one of the implementations will be kept by the linker (randomly) so one of your object file will call the implementation found in the other one resulting in wrong behavior and sometimes very hard to find bugs/crashes!!! Its easy to put inline functions/methods with different implementation into two object files, this usually happens without using headers! Let me demonstrate that:
x1.cpp:
C++
#include <stdio.h>

struct SInlineTest
{
	SInlineTest()
	{
		printf("%s 1\n", __FUNCTION__);
	}
	~SInlineTest()
	{
		printf("%s 1\n", __FUNCTION__);
	}
};


inline void InlineFunc()
{
	printf("%s 1\n", __FUNCTION__);
}

void InlineTest()
{
	SInlineTest t;
	InlineFunc();
}


x2.cpp:
C++
#include <stdio.h>

struct SInlineTest
{
    SInlineTest()
    {
        printf("%s 2\n", __FUNCTION__);
    }
    ~SInlineTest()
    {
        printf("%s 2\n", __FUNCTION__);
    }
};

inline void InlineFunc()
{
    printf("%s 2\n", __FUNCTION__);
}

void InlineTest2()
{
    SInlineTest t;
    InlineFunc();
}

int main()
{
    void InlineTest();
    InlineTest();
    printf("-----------------\n");
    InlineTest2();
    return 0;
}


Here the linker will keep only one of the InlineFunc() versions and the same is true for the constructors and the destructors. The linker will randomly throw out one of the versions. In case of class/struct declarations found inside .cpp files its advisable to put these class declarations into an anonymous namespace to avoid the linker conflict, in case of inline global function remove the "inline" keyword and either put the function into an anonymous namespace or use the static keyword or both is also valid.

EDIT: I've encountered this bug only twice in my life in case of bigger projects. This bug usually happens when two people use some small simple structs in two different .cpp files with the same name (like SItem - this is a popular name along with some other ones) and usually the inline ctor or dtor of these structs conflict resulting in a linking but misbehaving binary.
 
Share this answer
 
v4
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900