Встроенные конструкторы и одно правило определения
Рассмотрим следующие исходные файлы 1.cpp
#include <iostream>
using namespace std;
struct X
{
X()
{
cout << "1" << endl;
}
};
void bar();
void foo()
{
X x;
}
int main()
{
foo();
bar();
return 0;
}
файле 2.cpp
#include <cstdio>
struct X
{
X()
{
printf("2\n");
}
};
void bar()
{
X x;
}
Скомпилирована ли программа из этих файлов правильно? Что должно быть в его выводе?
Я ожидал ошибку компоновщика из-за нарушения правила одного определения или вывода "1 2". Однако он выводит "1 1" при компиляции с g++ 3.4 и VC 8.0.
Как это можно объяснить?
2 ответа
Это нарушает ODR (3.2) - в частности, вы можете иметь более одного определения встроенной функции, но эти определения должны быть идентичны (3.2/5) - и приводит к неопределенному поведению, поэтому может произойти все что угодно, и компилятор / компоновщик будет не требуется диагностировать это. Наиболее вероятная причина, по которой вы видите такое поведение, заключается в том, что вызовы функций являются встроенными и не участвуют в связывании, поэтому ошибка связи не возникает.
Это неопределенное поведение (без обязательной диагностики), если встроенные функции (например, конструктор вашего класса) имеют разные определения в разных единицах перевода.