¿Por qué una cadena vacía literal en una matriz multidimensional decae a un puntero nulo?

8

Quiero definir una matriz de cadenas C multidimensional, inicializada por varios literales de cadena. En C haría lo siguiente:

#include <stdio.h>

const char *strArr[2][1] = { {"foo"}, {""}};

int main(void) {
    printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
    return 0;
}

Compilar gcc -std=c18 -pedantic test.cy ejecutar resultados en:

$ ./a.out 
0x55d95410f004  0x55d95410f008

Como espero, el literal de cadena vacío en strArr[1][0]decae a un puntero válido.


Sin embargo, cuando intento el mismo código en C ++ :

#include <cstdio>

const char *strArr[2][1] = { {"foo"}, {""}};

int main(void) {
    printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
    return 0;
}

Compilar g++ -std=c++17 -pedantic test.cppy ejecutar resultados en:

$ ./a.out 
0x55c61494d004  (nil)

Aquí, el literal de cadena vacío se strArr[1][0]desintegra en un puntero nulo. ¿Por qué sucede esto en C ++?


En el estándar C ++ 17, veo lo siguiente en 5.13.5 párrafo 16 :

Los literales de cadena ordinarios y los literales de cadena UTF-8 también se denominan literales de cadena estrecha. Un literal de cadena estrecha tiene el tipo "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 (6.7).

Esto parece indicar que un literal de cadena vacío, al ser un literal de cadena normal, debe tener una duración de almacenamiento estático. Entonces, ¿por qué una cadena vacía literal se descompone en un puntero nulo?

Vilhelm Gray
fuente
1
¿Por qué usar una matriz de estilo C en primer lugar? ¿Por qué no std::array?
Jesper Juhl el
2
@super una cadena vacía tiene un carácter: el terminador. Cuando lo imprime, genera una nada válida.
Veleta
3
Esto es probablemente solo una regresión de GCC 9. Debes informarlo y ver lo que dicen.
Brian
2
g ++ hace esto, clang no: gcc.godbolt.org/z/XkZcVy Parece un error de g ++.
PSkocik
1
@KeithThompson La creación de la cuenta en el sitio de bugzilla de GCC está restringida, por lo que envié una solicitud por correo electrónico que espero cumplir mañana. Por ahora, he abierto un informe de error en Gentoo: bugs.gentoo.org/701364
Vilhelm Gray

Respuestas:

2

Este comportamiento no es correcto, y en este caso es el resultado de una regresión en GCC : https://gcc.gnu.org/PR90947

La regresión se ha corregido para GCC versión 9.3 y es de esperar que también regrese a las versiones anteriores afectadas.

Vilhelm Gray
fuente
0

No hay tal decadencia; el resultado que observó es un error del compilador.

(Sí, esta es una respuesta corta, pero no hay nada más que agregar).

MM
fuente
De los comentarios sobre la pregunta, es una regresión en g ++ 9, informada en Gentoo: bugs.gentoo.org/701364
Keith Thompson