2009-03-30 7 views
1

Играя с MSVC++ 2005, я заметил, что если один и тот же класс определен несколько раз, программа все еще счастливо соединяется даже на самом высоком уровне предупреждения. Я нахожу это удивительным, как получается, что это не ошибка?несколько определений одного и того же класса

module_a.cpp:

#include <iostream> 
struct Foo { 
    const char * Bar() { return "MODULE_A"; } 
}; 
void TestA() { std::cout << "TestA: " << Foo().Bar() << std::endl; } 

module_b.cpp:

#include <iostream> 
struct Foo { 
    const char * Bar() { return "MODULE_B"; } 
}; 
void TestB() { std::cout << "TestB: " << Foo().Bar() << std::endl; } 

main.cpp:

void TestA(); 
void TestB(); 
int main() { 
    TestA(); 
    TestB(); 
} 

И выход:

TestA: MODULE_A 
TestB: MODULE_A 

ответ

3

Это ошибка - код нарушает одно правило определения C++. Если вы это сделаете, стандарт говорит, что вы получаете неопределенное поведение.

Звенья код, потому что, если у вас:

struct Foo { 
    const char * Bar() { return "MODULE_B"; } 
}; 

в обоих модулях не было бы нарушением ODR - в конце концов, это в основном то, что #including заголовок делает. Нарушение происходит из-за того, что ваши определения различны (другая содержит строку «MODULE_A»), но для этого не существует способа для компоновщика (который просто смотрит на имена классов/функций).

0

Компилятор может считать, что объект бесполезен, кроме его использования в функции Test #(), и, следовательно, делает это целое. Таким образом, линкер никогда не увидит, что любой класс даже существовал! Правда, только идея.

Или каким-то образом связь между TestA и классом Foo [#] будет выполняться внутри компиляции. Был бы конфликт, если бы линкер искал класс Foo (множественное определение), но компоновщик просто не ищет его!

У вас есть ошибки связи при компиляции в режиме отладки без включения оптимизации?

+0

Не встраивается. Если бы результаты были правильными. Компилятор, вероятно, отбрасывает один (случайно выбранный) символ. Как указал Нил, если они оба были такими же, что было бы прекрасно. –

Смежные вопросы