¿Cuál es el tipo de literales de cadena en C y C++?

5 minutos de lectura

¿Cual es el tipo de literales de cadena en C
Falta el factor

¿Cuál es el tipo de cadena literal en C? Lo es char * o const char * o const char * const?

¿Qué hay de C++?

¿Cual es el tipo de literales de cadena en C
miguel rebabas

En C, el tipo de un literal de cadena es un char[] – que no es const según el tipo, pero es un comportamiento indefinido para modificar los contenidos. Además, 2 literales de cadena diferentes que tienen el mismo contenido (o suficiente del mismo contenido) pueden o no compartir los mismos elementos de matriz.

Del estándar C99 6.4.5/5 “Literales de cadena – Semántica”:

En la fase de traducción 7, se agrega un byte o código de valor cero a cada secuencia de caracteres multibyte que resulta de una cadena literal o literales. La secuencia de caracteres multibyte se usa luego para inicializar una matriz de duración de almacenamiento estático y la longitud suficiente para contener la secuencia. Para los literales de cadena de caracteres, los elementos de la matriz tienen tipo char, y se inicializan con los bytes individuales de la secuencia de caracteres multibyte; para cadenas literales anchas, los elementos de la matriz tienen tipo wchar_ty se inicializan con la secuencia de caracteres anchos…

No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores apropiados. Si el programa intenta modificar una matriz de este tipo, el comportamiento no está definido.

En C++, “Un literal de cadena ordinario tiene el tipo ‘matriz de n const char‘” (de 2.13.4/1 “Literales de cadena”). Pero hay un caso especial en el estándar C++ que hace que el puntero a literales de cadena se convierta fácilmente en punteros no calificados como constantes (4.2/2 “Conversión de matriz a puntero “):

Un literal de cadena (2.13.4) que no es un literal de cadena ancho se puede convertir en un valor r del tipo “puntero a char”; un literal de cadena ancha se puede convertir en un valor r del tipo “puntero a wchar_t”.

Como nota al margen, debido a que las matrices en C/C++ se convierten tan fácilmente en punteros, un literal de cadena a menudo se puede usar en un contexto de puntero, como cualquier matriz en C/C++.


Editorialización adicional: lo que sigue es en su mayoría especulación de mi parte sobre la justificación de las elecciones que hicieron los estándares C y C++ con respecto a los tipos de cadenas literales. Así que tómalo con pinzas (pero comenta si tienes correcciones o detalles adicionales):

Creo que el estándar C eligió hacer tipos literales de cadena sin const porque había (y hay) tanto código que espera poder usar no const-calificado char punteros que apuntan a literales. Cuando el const se agregó el calificador (que, si no me equivoco, se hizo alrededor del tiempo de estandarización de ANSI, pero mucho después de que K&R C hubiera estado presente para acumular una tonelada de código existente) si hacían punteros a literales de cadena que solo se podían asignar a char const* tipos sin molde casi todos los programas existentes habrían requerido cambios. No es una buena manera de conseguir que se acepte un estándar…

Creo que el cambio a C++ que los literales de cadena son const calificado se hizo principalmente para permitir que una cadena literal coincida de manera más apropiada con una sobrecarga que toma un “char const*” Argumento. Creo que también había un deseo de cerrar un agujero percibido en el sistema de tipos, pero el agujero fue abierto en gran medida por el caso especial en las conversiones de matriz a puntero.

El Anexo D del estándar indica que la “conversión implícita de calificación const a no const para cadenas literales (4.2) está en desuso”, pero creo que aún se rompería tanto código que pasará mucho tiempo antes de que los implementadores del compilador o el el comité de estándares está dispuesto a cerrar el enchufe (a menos que se pueda idear alguna otra técnica inteligente, pero entonces el agujero volvería, ¿no es así?).

El literal de cadena AC tiene tipo char [n] donde n es igual al número de caracteres + 1 para tener en cuenta el cero implícito al final de la cadena.

La matriz se asignará estáticamente; No lo es constpero modificarlo es un comportamiento indefinido.

Si tuviera tipo puntero char * o tipo incompleto char [], sizeof no pudo funcionar como se esperaba.

Hacer literales de cadena const es un modismo de C++ y no forma parte de ningún estándar de C.

Por varias razones históricas, los literales de cadena siempre fueron del tipo char[] C ª.

Al principio (en C90), se afirmó que modificar un literal de cadena invoca un comportamiento indefinido.

Sin embargo, no prohibieron tales modificaciones, ni hicieron cadenas literales. const char[] que hubiera tenido más sentido. Esto fue por razones de compatibilidad con el código anterior. Algunos sistemas operativos antiguos (sobre todo DOS) no protestaban si modificaba los literales de cadena, por lo que había muchos códigos de este tipo.

C todavía tiene este defecto hoy, incluso en el estándar C más reciente.

C++ heredó el mismo defecto de C, pero en los estándares posteriores de C++, finalmente crearon cadenas literales const (marcado como obsoleto en C++03, finalmente corregido en C++11).

Solían ser del tipo char[]. Ahora son de tipo const char[].

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad