2016-05-15 19 views
6

Perché il seguente codice viene compilato? Compila e funziona bene con clang e stampe first. Ma, credo che il comportamento corretto dovrebbe essere quello di lamentarsi e rilasciare un errore corretto.C++ Comportamento errato dell'inizializzazione std :: string

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s{ "first", "second" }; 
    std::cout << s << std::endl; 
} 

Questa domanda si ispira this.

+0

È perché la "prima" stringa ha un implicito "\ 0" alla fine di esso .... che dice all'oggetto 'stringa' di smettere di cercare altri caratteri (anche se probabilmente lo sta ancora assegnando completamente memoria del "secondo" a) – DarthRubik

+1

@DarthRubik: No. Questo non è ciò che sta accadendo. –

+0

Il problema di fondo è lo stesso di [questa domanda] (https://stackoverflow.com/questions/24112281/c11-initializer-list-fails-but-only-on-lists-of-length-2). – chris

risposta

9

std::string ha un costruttore di modelli che accetta due iteratori. Quando si passano i letterali stringa, questi decadranno a char const*, che si qualifica come iteratore. Tuttavia, poiché questi puntatori non formano un intervallo valido, hai un comportamento indefinito.

+0

Quindi, questo è un bug in clang; è corretto? –

+0

@EissaN. No. È un bug nel tuo codice. Il tuo programma esibisce un comportamento indefinito, e quindi clang non ha l'obbligo di fare nulla in particolare, e può, per quanto riguarda lo standard C++, fare qualsiasi cosa. –

4

Questo comportamento non è definito.

Si sta invocando un costruttore di std::string che accetta due iteratori, il valore di inizio e fine dell'iteratore. Poiché entrambi i parametri di inizializzazione hanno lo stesso tipo, vengono interpretati come una coppia di iteratori e corrispondono a questo particolare costruttore sovraccarico.

I valori dei puntatori di caratteri vengono interpretati come valori di inizio/fine dell'iteratore. Capita solo di lavorare con clang, ma con gcc questo genera un'eccezione.