2009-10-19 10 views

risposta

25

Sulla durata di conservazione:

2.13.4 ordinaria stringhe e UTF-8 stringhe sono anche indicati come strette stringhe letterali. Uno stretto stringa letterale ha tipo “vettore di n const char”, dove n è la dimensione della stringa come definito di seguito, ed ha una durata di stoccaggio statica

leggere unitamente 3.7.1

3.7.1.

Tutti gli oggetti che non hanno durata di archiviazione dinamica, non hanno durata di archiviazione thread e sono non locali hanno durata di archiviazione statica. L'archiviazione per questi oggetti deve durare per la durata del programma (3.6.2, 3.6.3).

On Tipo:

Allegato C

sottoparagrafo 2.13.4:

Cambio: stringhe letterali const fatto Il tipo di una stringa letterale è cambiato da "array di char" a "array of const char". Il tipo di char16_t stringa letterale viene modificato da "array of some-intero-type" a "array of const char16_t." Il tipo di una stringa letterale char32_t viene modificato da "array of some-intero-type" a "array of const char32_ - t.”Il tipo di un'ampia stringa letterale viene cambiato da‘vettore di wchar_t’a‘vettore di wchar_t const’

Rationale:. Ciò evita chiama una funzione sovraccaricata contenuti, che potrebbe aspettarsi di essere in grado di modificare la sua discussione.

Effetto sulla funzione originale: Passa alla semantica di funzionalità ben definita. Difficoltà di conversione: trasformazione sintattica semplice, perché i valori letterali stringa possono essere convertiti in char *; (4.2). I casi più comuni sono gestiti da una conversione standard nuova ma deprecata: char * p = "abc"; // valido in C, deprecato in C++ char * q = expr? "abc": "de"; // valido in C, non valida in C++

Come ampiamente utilizzato: programmi che hanno un motivo legittimo per il trattamento di stringhe letterali come puntatori a potenzialmente memoria modificabili sono probabilmente rare.

dinamicamente allocato (il termine 'mucchio' non viene mai utilizzata nel contesto di uno spazio di memoria AFAIK nello standard) memoria richiede una chiamata di funzione che può avvenire già la main tanto dopo la memoria statica viene allocata.

+0

+1 per la risposta corretta, ma la tua citazione da Standard non è esatta (almeno 2.13.4). –

+0

Può anche essere utile una citazione sull'utilizzo standard di C-Strings. Nel mondo C è più normale restituire un puntatore char * che è stato assegnato dinamicamente e quindi deve essere rilasciato. Se non segui questa convenzione, il tuo codice non funzionerà bene con le librerie esistenti che assumono questa convenzione. –

+1

@ Kirill V. Lyadvinsky: Questo è il progetto N-4411 del C++ 0x (menzionato in un commento da me). – dirkgently

13

Questo codice è perfettamente valido e conforme. L'unico "raggiro" sarebbe assicurarsi che il chiamante non provi a liberare la stringa.

+0

"Questo codice è perfettamente valido e conforme." Perché? –

+0

Non ce n'è bisogno. I valori letterali sono 'const char []' che non vengono mai assegnati all'heap. Il puntatore restituito sarà valido durante l'intera esecuzione del programma. –

+1

Non c'è "'const char []'" –

11

Questo codice è valido e conforme allo standard.

I valori letterali delle stringhe sono memorizzati nella memoria di sola lettura e la funzione ottiene solo l'indirizzo della stringa scelta.

C++ standard (2.13.4) dice:

Una stringa ordinaria letterale è di tipo “array di n const char” e la durata stoccaggio statico

Hanno la chiave per capire il vostro problema qui è la durata dell'archiviazione statica: i valori letterali delle stringhe vengono allocati all'avvio del programma e durano per la durata del programma. La tua funzione ottiene solo l'indirizzo e lo restituisce.

5

Tecnicamente Sì, è valido.
Le stringhe hanno una durata di archiviazione statica.

Ma non è tutta la storia.

Queste sono stringhe a C. La convenzione in C-Libraries e funtions è di restituire una stringa allocata dinamicamente che dovrebbe essere liberata. Ad esempio, un puntatore restituito passa implicitamente di nuovo alla proprietà del chiamante (come usuall in C ci sono anche delle eccezioni).

Se non si seguono queste convenzioni confonderai un sacco di esperti sviluppatori C che si aspetterebbero questa convenzione. Se non segui queste aspettative standard allora dovrebbe essere ben documentato nel codice.

Anche questo è C++ (come per i tag). Quindi è più convenzionale restituire una stringa std ::. La ragione di ciò è che il passaggio della proprietà tramite i puntatori è solo implicito (e questo ha comportato un sacco di errori nel codice C se l'aspettativa di cui sopra era stata interrotta ma documentata, sfortunatamente il documento non veniva mai letto dall'utente del codice). Usando una std :: string stai passando un oggetto e la loro non è più una questione di proprietà (il risultato è passato come valore e quindi tuo), ma poiché è un oggetto non ci sono domande o problemi con l'allocazione delle risorse .

Se siete preoccupati per l'efficienza, penso che sia una falsa preoccupazione.

Se si desidera che questo per la stampa tramite i flussi c'è già una convenzione standard per farlo:

std::cout << std::boolalpha << false << std::endl; 
std::cout << std::boolalpha << true << std::endl; 
Problemi correlati