Встроенные конструкторы и одно правило определения

Рассмотрим следующие исходные файлы 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) - и приводит к неопределенному поведению, поэтому может произойти все что угодно, и компилятор / компоновщик будет не требуется диагностировать это. Наиболее вероятная причина, по которой вы видите такое поведение, заключается в том, что вызовы функций являются встроенными и не участвуют в связывании, поэтому ошибка связи не возникает.

Это неопределенное поведение (без обязательной диагностики), если встроенные функции (например, конструктор вашего класса) имеют разные определения в разных единицах перевода.

Другие вопросы по тегам