Я знаю, что иногда компоновщик не замечает, что символ определяется несколько раз во всех входных данных, передаваемых компоновщику (файлы .obj и статические файлы .lib). И, конечно, иногда компоновщик замечает , что символ определен дважды, и выдает ошибку.
Но в приведенном ниже коде компоновщик замечает, что глобальная функция определяется дважды, и в то же время не , замечая, что статический метод класса определяется дважды. Все остальное равно.
Это нормально? Есть ли объяснение? Опять же, я понимаю, что компоновщик иногда никогда не замечает определения второго символа. Вопрос в том, в чем разница между глобальной функцией и статическим методом класса в отношении линкера и символов, определяемых несколько раз.
Спасибо, что нашли время помочь. Я бы почувствовал себя лучше, если бы понял, что здесь происходит. Вот три исходных файла, которые скомпилированы и связаны вместе.
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 - из вывода мы можем сказать, какое из определений было названо
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
}