2012-02-22 2 views
3

Tenir compte suivant les fichiers source 1.cppconstructeurs Inline et une définition Règle

#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; 
} 

est bien formé programme compilé à partir de ces fichiers? Ce qui devrait être dans sa sortie?

Je m'attendais à une erreur de l'éditeur de liens due à la violation de la règle de définition unique ou de la sortie "1 2". Cependant, il affiche "1 1" lorsqu'il est compilé avec g ++ 3.4 et VC 8.0.
Comment cela peut-il être expliqué?

+0

Si j'utilise '[[gnu :: noinline]]' pour les deux avec * clang 3.6.1 * alors la sortie est 1 1 sans respecter l'ordre des noms de fichiers spécifiés pour le compilateur et l'éditeur de liens. – Orient

Répondre

2

Cela enfreint ODR (3.2) - spécifiquement que vous pouvez avoir plus d'une définition d'une fonction inline, mais ces définitions doivent être identiques (3.2/5) - et conduit à un comportement indéfini, donc tout peut arriver et le compilateur/éditeur de liens n'est pas nécessaire pour diagnostiquer cela. La raison la plus probable pour laquelle vous voyez ce comportement est que les appels de fonction sont en ligne et ne participent pas à la liaison, donc aucune erreur de lien n'est émise.

+0

ODR ne s'applique pas aux fonctions en ligne. –

+0

@Kerrek SB: La description de la façon dont les fonctions inline doivent se comporter est la continuation de la description ODR. – sharptooth

+0

OK, assez juste :-) –

1

Il s'agit d'un comportement indéfini (sans diagnostic requis) si des fonctions en-ligne (telles que votre constructeur de classe) ont différentes définitions dans différentes unités de traduction.

+0

Pourquoi c'est UB? Les deux unités de traduction voient un 'X :: X' différent; Je suis d'accord que les deux sont dans la même portée mondiale. Mais alors qu'est-ce qui peut mal tourner à cause de ça? – iammilind

+2

@iammilind: Puisque 'X :: X' est en ligne, toutes les définitions de' X :: X' dans le programme entier doivent être identiques au niveau du jeton, sinon le comportement n'est pas défini. C'est l'exigence de 3.2/5. – sharptooth