Встроенные конструкторы и одно правило определения - PullRequest
3 голосов
/ 22 февраля 2012

Рассмотрим следующие исходные файлы 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;
}

* 1004 файл 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 ]

2 голосов
/ 22 февраля 2012

Это нарушает ODR (3.2) - в частности, вы можете иметь более одного определения встроенной функции, но эти определения должны быть идентичны (3.2 / 5) - и приводит к неопределенному поведению, поэтому может случиться что угодно, и компилятор/ Линкер не требуется для диагностики этого.Наиболее вероятная причина, по которой вы видите такое поведение, заключается в том, что вызовы функций встроены и не участвуют в связывании, поэтому ошибка связи не выдается.

1 голос
/ 22 февраля 2012

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

...