Consider this synthetic example. I have two native C++ projects in my Visual Studio 2010 solution. One is console exe and another is lib.
There are two files in lib:
// TImage.h
template<class T> class TImage
{
public:
TImage()
{
#ifndef _LIB
std::cout << "Created (main), ";
#else
std::cout << "Created (lib), ";
#endif
std::cout << sizeof(TImage<T>) << std::endl;
}
#ifdef _LIB
T c[10];
#endif
};
void CreateImageChar();
void CreateImageInt();
and
// TImage.cpp
void CreateImageChar()
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
}
void CreateImageInt()
{
TImage<int> image;
std::cout << sizeof(TImage<int>) << std::endl;
}
And one file in exe:
// main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
CreateImageChar();
CreateImageInt();
return 0;
}
I know, I shouldn't actually do like this, but this is just for understanding what is happening. And that's, what happens:
// cout:
Created (main), 1
1
Created (main), 1
10
Created (lib), 40
40
So how exactly this happened, that linker overrides lib's version of TImage<char>
with exe's version of TImage<char>
? But since there is no exe's version of TImage<int>
, it preserves lib's version of TImage<int>
?.. Is this behavior standardized, and if so, where can I found the description?
Update: Explanations of the effect given below are correct, thanks. But the question was "how exactly this happened"?.. I expected to get some linker error like "multiply defined symbols". So the most suitable answer is from Antonio Pérez's reply.