2013-08-24 21 views
5

Per curiosità, mi chiedo quale sia il vero tipo di base di una stringa letterale C++.Tipo di stringa letterale C++

A seconda di ciò che osservo, ottengo risultati diversi.

Un test typeid simile al seguente:

std::cout << typeid("test").name() << std::endl; 

mi char const[5] mostra.

tentando di assegnare una stringa letterale a un tipo non compatibile in questo modo (per vedere l'errore data):

wchar_t* s = "hello"; 

ricevo a value of type "const char *" cannot be used to initialize an entity of type "wchar_t *" da IntelliSense di VS12.

Ma non vedo come potrebbe essere const char * come la seguente riga è accettato da VS12:

char* s = "Hello"; 

Ho letto che questo è stato consentito in standard pre-C++ 11 come è stato per retro-compatibilità con C, anche se la modifica di s risulterebbe in comportamento non definito. Presumo che questo sia semplicemente VS12 che non ha ancora implementato tutto lo standard C++ 11 e che questa riga normalmente genera un errore.

lettura standard C99 (from here, 6.4.5.5) suggerisce che dovrebbe essere un array:

Il carattere sequenza multibyte viene quindi utilizzato per inizializzare un array di durata di conservazione statico e lunghezza appena suf fi ciente per contenere la sequenza.

Quindi, qual è il tipo al di sotto di una stringa C++ letterale?

Grazie mille per il vostro tempo prezioso.

+5

VS12 parla un po 'strano dialetto che è simile, ma non identico, C++. –

risposta

8

Il tipo di stringa letterale è infatti dove SIZE è la lunghezza della stringa più il carattere di terminazione null.

Il fatto che a volte si veda const char* è dovuto al solito decadimento da matrice a puntatore.

Ma non vedo come potrebbe essere const char * come la seguente riga è accettato da VS12: char* s = "Hello";

Questo è stato corretto comportamento in C++ 03 (come eccezione al solito regole di const-correctness) ma è stato deprecato da allora. Un compilatore compatibile con C++ 11 non dovrebbe accettare quel codice.

+2

Il "normale decadimento array-to-pointer" non si verifica in tutti i contesti. In C, si verifica a meno che l'espressione dell'array non sia l'operando di unario '&' o 'sizeof', o sia una stringa letterale in un inizializzatore usato per inizializzare un oggetto array (sotto). Il C++ ha più eccezioni. –

+0

Il termine corretto è _ Conversione da array a puntatore_, che è una _ Conversione standard_ documentata nella clausola 4 dell'ultimo standard C++. In parole povere, le conversioni standard possono essere applicate implicitamente alle espressioni del compilatore in determinati contesti. –

5

Il tipo di stringa letterale è char const[N] dove N è il numero di caratteri compreso il carattere nullo di chiusura. Sebbene questo tipo non sia non convertito in char*, lo standard C++ include una clausola che consente l'assegnazione di stringhe letterali a char*.Questa clausola è stata aggiunta per supportare la compatibilità soprattutto per il codice C che non aveva const.

La clausola relativa al tipo nello standard è 2.14.5 [lex.string] comma 8:

ordinarie stringhe letterali e UTF-8 stringhe letterali sono indicati anche come strette stringhe letterali. Un letterale stringa stretto ha tipo "array of n const char", dove n è la dimensione della stringa come definito di seguito e ha durata di archiviazione statica (3.7).

+1

Si noti che questa clausola eccezionale è ora deprecata e il tentativo di assegnare una stringa letterale a un 'char *' dovrebbe produrre un errore in fase di compilazione. – syam

+0

@syam - "deprecato" significa che è ancora legale, ma potrebbe andare via in futuro. La conversione di una stringa letterale in un 'char *' è stata deprecata in C++ 03; è diventato non valido in C++ 11. Tuttavia, la definizione della lingua non richiede un "errore in fase di compilazione". Per le violazioni dei vincoli diagnosticabili, l'unico requisito è che il compilatore emetta una diagnostica; Fatto ciò, è libero di continuare a compilare il codice. Questo è l'aggancio per le estensioni specifiche dell'implementazione. C'è solo una situazione che richiede che un compilatore rifiuti di compilare il codice: una direttiva '# error'. –

-1

Innanzitutto, il tipo di una stringa C++ letterale è un array di nconst char. In secondo luogo, se si desidera inizializzare un wchar_t con una stringa letterale è necessario il codice:

wchar_t* s = L"hello" 
+0

Questo non voleva essere un codice valido, solo un test per vedere l'errore dato. Lo standard fa davvero sembrare che dovrebbe essere un array, però. –

+7

No, una stringa letterale non è un 'const char *' ma un 'const char [SIZE]' come spiegato in altre risposte. -1 – syam

+1

Quindi spiega perché 'sizeof" ciao, mondo "restituisce 13. –

Problemi correlati