I know that sometimes the linker does not notice that a symbol is defined multiple times across all the input given to the linker (.obj files and static .lib files). And of course sometimes the linker does notice that a symbol is defined twice and gives an error.
But in the code below, the linker does notice that a global function is defined twice while at the same time not noticing that a class static method is defined twice. Everything else is equal.
Is this normal? Is there an explanation? Again, I get it that the linker sometimes never notices the second symbol definition. The question is what the difference is between the global function and class static method with regard to the linker and symbols being defined multiple times.
Thanks for taking the time to help. I'd feel better if I understood what was going on here. Here are three source files that are compiled and linked together.
TranslationUnit1.cpp:
// First definition of GlobalFunc()
void GlobalFunc() {std::cout << "GlobalFunc() in Translation Unit 1" << std::endl;}
void GlobalFunc_TransUnit1() {GlobalFunc();}
struct Foo
{
// First definition of Foo::ClassStaticFunc()
static void ClassStaticFunc() {std::cout << "Foo::ClassStaticFunc() in Translation Unit 1" << std::endl;}
};
void ClassStaticFunc_TransUnit1() {Foo::ClassStaticFunc();}
TranslationUnit2.cpp:
// Second definition of GlobalFunc()
void GlobalFunc() {std::cout << "GlobalFunc() in Translation Unit 2" << std::endl;}
void GlobalFunc_TransUnit2() {GlobalFunc();}
struct Foo
{
// Second definition of Foo::ClassStaticFunc()
static void ClassStaticFunc() {std::cout << "Foo::ClassStaticFunc() in Translation Unit 2" << std::endl;}
};
void ClassStaticFunc_TransUnit2() {Foo::ClassStaticFunc();}
Main.cpp - from the output we can tell which of definition was called
void GlobalFunc_TransUnit1();
void GlobalFunc_TransUnit2();
void ClassStaticFunc_TransUnit1();
void ClassStaticFunc_TransUnit2();
int main(int argc, char** argv)
{
// This won't link (as expected).
// The linker reports that GlobalFunc() is defined twice.
GlobalFunc_TransUnit1();
GlobalFunc_TransUnit2();
// This links despite Foo::ClassStaticFunc() being defined twice.
// In the final executable, both ClassStaticFunc_TransUnit1() and
// ClassStaticFunc_TransUnit2() call the same Foo::ClassStaticFunc() -
// which happens to be the definition in TranslationUnit1.cpp
ClassStaticFunc_TransUnit1(); // Calls Foo::ClassStaticFunc() in TranslationUnint1.cpp
ClassStaticFunc_TransUnit2(); // Also calls Foo::ClassStaticFunc() in TranslationUnit1.cpp
}
.h
file and there should be only 1 definition. This might compile, but it's not a well defined program. – super