Por que uma string vazia literal em uma matriz multidimensional decai para um ponteiro nulo?

8

Eu quero definir uma matriz multidimensional de string C, inicializada por vários literais de string. Em C, eu faria o seguinte:

#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;
}

Compilando gcc -std=c18 -pedantic test.ce executando resultados em:

$ ./a.out 
0x55d95410f004  0x55d95410f008

Como eu esperava, a string vazia literal se strArr[1][0]deteriora para um ponteiro válido.


No entanto, quando tento o mesmo código em 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;
}

Compilando g++ -std=c++17 -pedantic test.cppe executando resultados em:

$ ./a.out 
0x55c61494d004  (nil)

Aqui, a string vazia literal se strArr[1][0]deteriora para um ponteiro nulo. Por que isso acontece em C ++?


No padrão C ++ 17, vejo o seguinte no parágrafo 5.13.5 16 :

Literais de sequência ordinária e literais de sequência UTF-8 também são chamados de literais de sequência estreita. Um literal de cadeia estreita tem o tipo "array de n const char", em que n é o tamanho da cadeia, conforme definido abaixo, e tem duração de armazenamento estático (6.7).

Isso parece indicar que um literal de string vazio, sendo um literal de string comum, deve ter duração de armazenamento estático. Então, por que uma string vazia literal se deterioraria para um ponteiro nulo?

Vilhelm Grey
fonte
1
Por que usar uma matriz de estilo C em primeiro lugar? Por que não std::array?
Jesper Juhl
2
@super uma string vazia tem um caractere: o terminador. Quando você imprime, ele gera um valor válido.
Weather Vane
3
Provavelmente é apenas uma regressão do GCC 9. Você deve denunciá-lo e ver o que eles dizem.
27719 Brian
2
O g ++ faz isso, o clang não: gcc.godbolt.org/z/XkZcVy Parece um bug do g ++.
PSKocik
1
A criação da conta @KeithThompson no site de bugzilla do GCC é restrita. Por isso, enviei uma solicitação de e-mail que, esperamos, seja atendida amanhã. Por enquanto, eu abri um relatório de bug no Gentoo: bugs.gentoo.org/701364
Vilhelm Gray

Respostas:

2

Esse comportamento não está correto e, neste caso, é o resultado de uma regressão no GCC : https://gcc.gnu.org/PR90947

A regressão foi corrigida para a versão 9.3 do GCC e, esperamos, também deve retornar às versões anteriores afetadas.

Vilhelm Grey
fonte
0

Não existe tal decadência; a saída que você observou é um erro do compilador.

(Sim, esta é uma resposta curta, mas não há mais nada a acrescentar).

MILÍMETROS
fonte
A partir dos comentários sobre a questão, é uma regressão em g ++ 9, relatada no Gentoo: bugs.gentoo.org/701364
Keith Thompson