Costruttori inline e una regola di definizione
-
29-10-2019 - |
Domanda
Considera i seguenti file sorgente 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;
}
Il programma compilato da questi file è ben formato?Cosa dovrebbe esserci nel suo output?
Mi aspettavo un errore del linker dovuto alla violazione di una regola di definizione o all'output "1 2".Tuttavia stampa "1 1" quando viene compilato con g ++ 3.4 e VC 8.0.
Come può essere spiegato?
Soluzione
Questo viola ODR (3.2) - in particolare che puoi avere più di una definizione di una funzione inline, ma quelle definizioni devono essere identiche (3.2 / 5) - e porta a un comportamento indefinito, quindi può succedere qualsiasi cosa e il compilatore/ linker non è necessario per la diagnosi.Il motivo più probabile per cui vedi questo comportamento è che le chiamate di funzione sono inline e non partecipano al collegamento, quindi non viene emesso alcun errore di collegamento.
Altri suggerimenti
È un comportamento indefinito (senza diagnostica richiesta) se le funzioni inline (come il costruttore della classe) hanno definizioni differenti in unità di traduzione differenti.