2012-02-29 12 views
6

Perché l'output del seguente programma è solo int3 e non int3&4?Il costruttore di copia con parametri predefiniti non viene mai chiamato

#include <iostream> 

class B 
{ 
public: 
    explicit B(int i) { std::cout<<"int"<<i; } 
    B(const B& rhs, int i = 0) { std::cout<<"&"<<i; } 
}; 

int main(int, char**) 
{ 
    B b(B(3), 4); 
} 

Comando: clang++ test.cpp -O0

Compiler: Apple versione 3.0 clang (tag/Apple/clang-211,12) (sulla base degli LLVM 3.0svn)

+0

Stampa 'int3 & 4' per me (GCC 4.6.2,' -O3'). –

+0

In realtà il mio g ++ 4.6.1 stampa "int3 e 4". – Duck

+1

+1 in breve, test case completo. http://sscce.org –

risposta

1

Questo era un bug in clang, che ha since been fixed. Copy-elision non è stato applicato correttamente alla chiamata del costruttore, perché clang non stava verificando quanti argomenti sono stati forniti prima di concludere che si trattava di una costruzione di copia.

La correzione sarà nella prossima versione di clang 3.1.

3

Sembra che si potrebbe avere trovato un capriccio compilatore:)

Se si cambia la versione del compilatore a tutto ciò che non LLVM 3.0, l'uscita è INT3 & 4.

Questo stampa i NT3 & 4 su LLVM 3.0, così sembra essere correlato al fatto che B (3) è un oggetto temporaneo:

class B 
{ 
public: 
    explicit B(int i) 
    { 
     std::cout<<"int"<<i; 
    } 
    B(const B& rhs, int i = 0) 
    { 
     std::cout<<"&"<<i; 
    } 
}; 

int main(int, char**) 
{ 
    B a(3); 
    B b(a, 4); 
} 
+0

Sì, questo era un bug in clang, che da allora è stato corretto. Copy-elision non è stato applicato correttamente alla chiamata del costruttore, perché clang non stava verificando quanti argomenti sono stati forniti prima di concludere che si trattava di una costruzione di copia. –

+0

@RichardSmith Puoi pubblicare questo commento come risposta? –

0

Molto probabilmente, RVO e NRVO mangiato il vostro codice. Queste condizioni speciali consentono al compilatore di eliminare in silenzio le copie dell'oggetto che sarebbero altrimenti applicate dalla lingua. Poiché nessuna copia è mai stata creata come risultato, il codice non stampa mai l'istruzione nel costruttore di copie.

+0

RVO e NRVO potrebbero essere consentiti anche in modalità di debug? A quanto ho capito, sono ottimizzazioni e quindi dovrebbero essere disabilitate quando si esegue in modalità Debug, ma in modalità Debug anche "int3", su LLVM 3.0 – Carl

+0

Ho solo pensato di aggiungere questo: http://stackoverflow.com/ domande/8556608/cosa-posso-i-ragionevolmente-aspetta-a-compilatore-to-be-grado-per-linea. Apparentemente, alcuni compilatori implementano in modo selettivo RVO e/o NRVO in modalità di debug, il che spiegherebbe il comportamento di LLVM. – Carl

+0

@carleeto: il compilatore può legalmente farlo quando vuole. – Puppy

Problemi correlati