2014-09-01 15 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; 
} 

uscite 4 e 3.Si sta utilizzando una funzione membro come argomento per un comportamento non definito del costruttore?

Si chiama una funzione membro prima di chiamare il costruttore. Il comportamento è definito dallo standard?

+8

Sì, questo comportamento non è definito. Stai chiamando una funzione membro su una variabile che non è stata ancora inizializzata. – Mankarse

+1

'A * bar = NULL;' 'bar-> foo();' funzionerà anche .. Solo così sai. È comunque indefinito. Ho anche provato qualcosa del tipo: 'char buffer [256]; A * bar = (A *) e buffer [0]; bar-> foo(); 'funziona anche .. Ancora indefinito. – Brandon

+1

Perché questo è permesso a tutti? Come mai puoi accedere a 'a' prima che la sua dichiarazione sia finita? – Irfy

risposta

31

§12.7 [class.cdtor]/p1:

Per un oggetto con un costruttore non banale, si riferiscono a qualsiasi non statico classe membro o base dell'oggetto prima del costruttore inizia l'esecuzione si traduce in un comportamento indefinito.

Un compilatore conforme è autorizzato a emettere codice che spazza via le gambe.

+0

Ciò che conta come un ctor non banale? – Davor

+6

@Davor In sostanza, qualsiasi costruttore che fa qualcosa. –

+1

Non è un costruttore vuoto anche non banale @ T.C. ? –

4

Sì. In pratica, potrebbe funzionare, poiché A::foo non rileva nessuno stato dall'istanza a. Non dovresti mai scrivere codice come questo (e probabilmente dovresti correggerlo).

Problemi correlati