2009-10-19 13 views

Respuesta

25

En el tiempo de almacenamiento:

2.13.4 cadenas literales ordinarias y UTF-8 literales de cadena también se les conoce como literales de cadena estrechas. A cadena estrecha literal tiene que escribir “matriz de n const char”, donde n es el tamaño de la cadena como se define a continuación, y tiene una duración de almacenamiento estático

en relación con 3.7.1

3.7.1.

Todos los objetos que no tienen una duración de almacenamiento dinámico, no tienen duración de almacenamiento de subprocesos y son no locales tienen duración de almacenamiento estático. El almacenamiento para estos objetos durará por la duración del programa (3.6.2, 3.6.3).

Por tipo:

Anexo C

el numeral 2.13.4:

Cambio: Los literales de cadena hecha const El tipo de una cadena literal es cambiado de "array of char" a "array of const char". El tipo de un char16_t cadena literal se cambia de "matriz de tipo entero-tipo" a "matriz de const char16_t". El tipo de un literal de cadena char32_t se cambia de "matriz de tipo entero-tipo" a "matriz de const char32_ - t.”El tipo de una amplia cadena literal se cambia de‘gama de wchar_t’a‘conjunto de const wchar_t’

Justificación:. Esto evita llamar a una función sobrecargada inapropiada, lo que podría esperar ser capaz de modificar su argumento.

Efecto en la función original: Cambio a la semántica de la función bien definida. Dificultad de conversión: transformación sintáctica simple, porque los literales de cadena se pueden convertir a char *; (4.2). Los casos más comunes son manejados por una conversión estándar nueva pero en desuso: char * p = "abc"; // válido en C, desaprobado en C++ char * q = expr? "a B C D e"; // válida en C, C++ válida en

Cómo ampliamente utilizado: Los programas que tienen una razón legítima para tratar los literales de cadena como punteros a potencialmente modificable de memoria son probablemente raros.

dinámicamente asignada (la palabra 'Pila' nunca se utiliza en el contexto de un área de memoria que yo sepa en la norma) de memoria requiere una llamada de función que puede ocurrir tan pronto como main mucho después de que se asigna la memoria estática.

+0

+1 para la respuesta correcta, pero su cita de Standard no es exacta (al menos 2.13.4). –

+0

Una cita sobre el uso estándar de C-Strings también puede ser útil. En el mundo C, es más estándar devolver un puntero char * que se asignó dinámicamente y, por lo tanto, es necesario liberarlo. Si no sigue esta convención, su código no funcionará bien con las bibliotecas existentes que asumen esta convención. –

+1

@Kirill V. Lyadvinsky: Esto es del borrador C++ 0x N-4411 (mencionado en un comentario hecho por mí). – dirkgently

13

Este código es perfectamente válido y conforme. El único "gotcha" sería asegurar que la persona que llama no intente liberar la cadena.

+0

"Este código es perfectamente válido y conforme". ¿Por qué? –

+0

No es necesario. Los literales son 'const char []' que nunca se asignan al montón. El puntero devuelto será válido durante toda la ejecución del programa. –

+1

No hay "'const char []'" –

11

Este código es válido y cumple con las normas.

Los literales de cadena se almacenan en la memoria de solo lectura, y la función simplemente obtiene la dirección de la cadena elegida.

estándar de C++ (2.13.4) dice:

Una cadena literal ordinaria tiene tipo “arreglo de char const n” y la duración de almacenamiento estático

clave que entender su problema aquí está la duración del almacenamiento estático: los literales de cadena se asignan cuando se inicia el programa, y ​​duran por la duración del programa. Su función solo obtiene la dirección y la devuelve.

5

Técnicamente Sí, es válido.
Las cadenas tienen durataion de almacenamiento estático.

Pero esa no es toda la historia.

Estos son C-Strings. La convención en C-Libraries y funciones es devolver una cadena asignada dinámicamente que debe ser liberada. es decir, un puntero devuelto devuelve implícitamente la propiedad a la persona que llama (como es habitual en C, también hay excepciones).

Si no sigue estas convenciones, confundirá a muchos C-Desarrolladores experimentados que esperarían esta convención. Si no sigue esta expectativa estándar, entonces debe estar bien documentada en el código.

También esto es C++ (según sus etiquetas). Por lo tanto, es más convencional devolver una std :: string. La razón de esto es que el paso de propiedad a través de punteros solo está implícito (y esto condujo a muchos errores en el código C si la expectativa anterior se rompiera pero estuviera documentada, desafortunadamente la documentación nunca fue leída por el usuario del código). Al usar std :: string está pasando un objeto y ya no se trata de la propiedad (el resultado se pasa como un valor y por lo tanto el suyo), pero como es un objeto, no hay preguntas ni problemas con la asignación de recursos. .

Si le preocupa la eficacia, creo que es una preocupación falsa.

Si desea que esta para imprimir a través de las corrientes ya existe una convención estándar para hacer eso:

std::cout << std::boolalpha << false << std::endl; 
std::cout << std::boolalpha << true << std::endl; 
Cuestiones relacionadas