2014-09-01 6 views
19
#include <cstdio> 

class A 
{ 
public: 
    A(int){puts("3");}; 

    int foo(){puts("4");return 10;} 
}; 

int main() 
{ 
    A a(a.foo()); 
    return 0; 
} 

Wyjścia 4 i 3.Używa funkcji składowej jako argumentu do niezdefiniowanego zachowania konstruktora?

To wywołuje funkcję składową przed wywołaniem konstruktora. Czy zachowanie jest zdefiniowane przez standard?

+8

Tak, to jest niezdefiniowane zachowanie. Wywołujesz funkcję członkowską na zmiennej, która nie została jeszcze zainicjalizowana. – Mankarse

+1

'A * bar = NULL;' 'bar-> foo();' również będzie działał .. Tak, żebyś wiedział. Jest jednak niezdefiniowany. Próbowałem również coś takiego: 'char buffer [256]; A * bar = (A *) i bufor [0]; bar-> foo(); 'działa też ... Ciągle nieokreślony. – Brandon

+1

Dlaczego jest to w ogóle dozwolone? Jak możesz uzyskać dostęp do "a" zanim jego deklaracja się skończy? – Irfy

Odpowiedz

31

§12.7 [class.cdtor]/P1:

Dla obiektu, z nietrywialną konstruktora, odnosząc się do każdego niż statyczna składowa lub zasady klasy obiektu przed konstruktora rozpoczyna wykonywanie powoduje niezdefiniowane zachowanie.

Kompatybilny kompilator może emitować kod, który wysadzi ci nogi.

+0

Co należy traktować jako nietrywialny ctor? – Davor

+6

@Davor W zasadzie każdy konstruktor, który coś robi. –

+1

Nie jest pustym konstruktorem również niebanalnym @ T.C. ? –

4

Tak. W praktyce może działać, ponieważ A::foo nie tworzy żadnego stanu z instancji a. Nigdy nie powinieneś pisać takiego kodu (i prawdopodobnie powinieneś go poprawić).