Рассмотрим следующий пример:
// usedclass1.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 1 (" << this << ") doit hit" << std::endl; }
};
// usedclass2.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 2 (" << this << ") doit hit" << std::endl; }
};
// object.hpp
class Object
{
public:
Object();
};
// object.cpp
#include "object.hpp"
#include "usedclass2.hpp"
Object::Object()
{
UsedClass b;
b.doit();
}
// main.cpp
#include "usedclass1.hpp"
#include "object.hpp"
int main()
{
Object obj;
UsedClass a;
a.doit();
}
Код компилируется без каких-либо ошибок компилятора или компоновщика. Но вывод для меня странный:
gcc (Red Hat 4.6.1-9) на Fedora x86_64 без оптимизации [EG1]:
UsedClass 1 (0x7fff0be4a6ff) doit hit
. UsedClass 1 (0x7fff0be4a72e) doit hit
то же, что и [EG1], но с включенной опцией -O2 [EG2]:
UsedClass 2 (0x7fffcef79fcf) doit hit
UsedClass 1 (0x7fffcef79fff) doit hit
msvc2005 (14.00.50727.762) на Windows XP 32bit без оптимизации [EG3]:
UsedClass 1 (0012FF5B) doit hit
UsedClass 1 (0012FF67) doit hit
то же, что и [EG3], но с включенным /O2 (или /Ox) [EG4]:
UsedClass 1 (0012FF73) doit hit
UsedClass 1 (0012FF7F) doit hit
Я бы ожидал либо ошибку компоновщика (предполагая, что нарушено правило ODR), либо вывод, как в [EG2] (код инлайнится, ничего не экспортируется из блока трансляции, правило ODR соблюдается). Итак, мои вопросы:
Спасибо за любые предложения, комментарии и толкования стандарта.
Обновление
Хотелось бы понять поведение компилятора. Точнее, почему не выдаются ошибки при нарушении УСО. Есть гипотеза, что поскольку все функции в классах UsedClass1 и UsedClass2 помечены как inline (и поэтому C++03 3.2 не нарушен), то компоновщик не сообщает об ошибках, но в этом случае выходы [EG1], [EG3], [EG4] выглядят странно.