No hay error del compilador cuando se inicializa la matriz de caracteres de tamaño fijo sin espacio suficiente para el terminador nulo

2 minutos de lectura

avatar de usuario
Traumatismos digitales

Supongamos que tengo las siguientes matrices de caracteres c:

char okaysize4[5] = "four";   // line 5
char toosmall4[4] = "four";   // line 6
char toosmall3[3] = "four";   // line 7

Cuando compilo con gcc 4.4.7, aparece el siguiente error:

array.c:7: advertencia: la cadena de inicialización para la matriz de caracteres es demasiado larga

Se espera este error para la línea 7, ya que estoy tratando de rellenar 5 caracteres ("four" + \0) en una matriz de 3 elementos. Además, no se espera ningún error para la línea 5, ya que la matriz de 5 elementos es lo suficientemente grande.

Sin embargo, me sorprende que no haya un error similar para la línea 6. Lo que termina inicializándose en toosmall4 es una cadena sin terminar, que puede causar todo tipo de problemas.

Tengo entendido que el literal de cadena c "four" debe tener cinco caracteres, debido al terminador nulo. De hecho sizeof("four") es 5. Entonces, ¿por qué el compilador no da un error aquí?

¿Hay alguna forma en que pueda modificar mi declaración/definición/inicialización para que se marque un error en este caso?

avatar de usuario
Shafik Yaghmour

Este es el comportamiento esperado para la línea 6, desde el borrador del estándar C99 sección 6.7.8 Inicialización párrafo 14 dice (énfasis mío):

Una matriz de tipo de carácter puede inicializarse mediante una cadena de caracteres literal, opcionalmente encerrada entre llaves. Caracteres sucesivos del literal de cadena de caracteres (incluido el carácter nulo de terminación si hay espacio o si la matriz es de tamaño desconocido) inicializar los elementos de la matriz.

En el proyecto de norma C11, la sección pertinente con una redacción similar es 6.7.9 párrafo 14y como el C Preguntas frecuentes dice:

Por lo tanto, la matriz no es una verdadera cadena C y no se puede usar con strcpy, el formato %s de printf, etc.

Como señaló Keith Thompson, C++ es más estricto, la sección correspondiente en el borrador del estándar C++ dice lo siguiente:

No habrá más inicializadores que elementos de matriz.[Ejemplo:[Example:

char cv[4] = "asdf"; // error

está mal formado ya que no hay espacio para el ‘\0’ final implícito. —fin del ejemplo]

  • Esta característica ha estado en C desde siempre.

    –Jim Balter

    20 de diciembre de 2013 a las 5:52

es legal, toosmall4 no es una cadena, sino una matriz de caracteres válida (sin el carácter nulo de terminación).

Referencia: Preguntas frecuentes.

¿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