c++ - perrones - grupo exterminador entre perico y perico
¿Qué estándares de idioma permiten ignorar los terminadores nulos en matrices de tamaño fijo? (2)
Estamos haciendo la transición del código C a C ++.
Noté que el siguiente código está bien definido en C,
int main(){
//length is valid. ''/0'' is ignored
char str[3]="abc";
}
como se indica en la inicialización de Array que:
"Si se conoce el tamaño de la matriz, puede ser uno menos que el tamaño del literal de cadena, en cuyo caso se ignora el carácter nulo de terminación".
Sin embargo, si construyera el mismo código en C ++, obtengo el siguiente error de C ++:
error: initializer-string for array of chars is too long
[-fpermissive] char str[3]="abc";
Espero que alguien pueda exponer sobre esto.
Preguntas:
¿Es el código de ejemplo válido en todos los estándares de lenguaje C?
¿Es inválido en todos los estándares de lenguaje C ++?
¿Hay alguna razón válida en un idioma pero no en otro?
¿Es el código de ejemplo válido en todos los estándares de lenguaje C?
Tenga en cuenta que solo una norma ISO está vigente a la vez; C2011 reemplaza a C99, que reemplazó a C89.
Sin embargo, creo que debería ser válido bajo cualquiera de esos estándares.
¿Es inválido en todos los estándares de lenguaje C ++?
Igual que el anterior, simplemente cambie "válido" a "inválido".
¿Hay alguna razón válida en un idioma pero no en otro?
Lo más probable es que se dejara válido en C para no romper ningún código heredado que se basara en el comportamiento. C ++ llegó aproximadamente una década después de C e intentó solucionar algunos de los defectos de C, y este fue uno de los agujeros que se taparon.
Muchos lenguajes de programación modernos son iteraciones y mejoras en lenguajes anteriores; C es B con un sistema de tipos, C ++ es C con soporte de OO y mejor seguridad de tipos, Java y C # son C ++ con menos comportamiento indefinido, etc.
Lo que se ve aquí es una diferencia en las reglas de inicialización para la fijación de cadenas en C y C ++. En C11 §6.7.9 / 14 tenemos
Una matriz de tipo de caracteres puede inicializarse mediante un literal de cadena de caracteres o un literal de cadena UTF-8, opcionalmente entre llaves. Los bytes sucesivos de la cadena literal ( incluido el carácter nulo de terminación si hay espacio o si la matriz es de tamaño desconocido) inicializan los elementos de la matriz.
énfasis mio
Entonces, siempre que la matriz sea lo suficientemente grande como para que la cadena excluya el terminador nulo es válida. Asi que
char str[3]="abc";
Es válido C. En C ++ 14, sin embargo, la regla que gobierna esto se encuentra en [dcl.init.string] / 2 estados
No habrá más inicializadores que elementos de matriz.
Y continúa para mostrar que el siguiente código es un error
char cv[4] = "asdf"; // error
Por lo tanto, en C ++ debe tener suficiente almacenamiento para el literal de la cadena completa, incluido el terminador nulo.