Warum zerfällt ein leeres String-Literal in einem mehrdimensionalen Array in einen Nullzeiger?

8

Ich möchte ein mehrdimensionales C-String-Array definieren, das durch mehrere String-Literale initialisiert wird. In C würde ich folgendes tun:

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

Kompilieren mit gcc -std=c18 -pedantic test.cund Ausführen von Ergebnissen in:

$ ./a.out 
0x55d95410f004  0x55d95410f008

Wie ich erwartet habe, strArr[1][0]zerfällt das leere String-Literal in einen gültigen Zeiger.


Wenn ich jedoch denselben Code in C ++ versuche :

#include <cstdio>

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

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

Kompilieren mit g++ -std=c++17 -pedantic test.cppund Ausführen von Ergebnissen in:

$ ./a.out 
0x55c61494d004  (nil)

Hier strArr[1][0]zerfällt das leere String-Literal in einen Nullzeiger. Warum passiert das in C ++?


Im C ++ 17-Standard sehe ich in 5.13.5 Absatz 16 Folgendes :

Gewöhnliche String-Literale und UTF-8-String-Literale werden auch als schmale String-Literale bezeichnet. Ein schmales String-Literal hat den Typ "Array von n const char", wobei n die Größe des Strings ist, wie unten definiert, und eine statische Speicherdauer (6.7) hat.

Dies scheint darauf hinzudeuten, dass ein leeres String-Literal als gewöhnliches String-Literal eine statische Speicherdauer haben sollte. Warum sollte ein leeres String-Literal in einen Nullzeiger zerfallen?

Vilhelm Gray
quelle
1
Warum überhaupt ein Array im C-Stil verwenden? Warum nicht std::array?
Jesper Juhl
2
@super Eine leere Zeichenfolge hat ein Zeichen: den Terminator. Wenn Sie es drucken, wird ein gültiges Nichts ausgegeben.
Wetterfahne
3
Dies ist wahrscheinlich nur eine GCC 9-Regression. Sie sollten es melden und sehen, was sie sagen.
Brian
2
g ++ macht das, clang nicht: gcc.godbolt.org/z/XkZcVy Sieht aus wie ein g ++ - Fehler.
PSkocik
1
Die Erstellung des @ KeithThompson-Kontos auf der GCC-Bugzilla-Website ist eingeschränkt. Daher habe ich eine E-Mail-Anfrage gesendet, die hoffentlich bis morgen erfüllt sein wird. Im Moment habe
Vilhelm Gray

Antworten:

2

Dieses Verhalten ist nicht korrekt und in diesem Fall das Ergebnis einer Regression im GCC : https://gcc.gnu.org/PR90947

Die Regression wurde für GCC Version 9.3 behoben und sollte hoffentlich auch zu den früheren betroffenen Versionen zurückkehren.

Vilhelm Gray
quelle
0

Es gibt keinen solchen Verfall; Die Ausgabe, die Sie beobachtet haben, ist ein Compiler-Fehler.

(Ja, dies ist eine kurze Antwort, aber es gibt nichts hinzuzufügen).

MM
quelle
Aus den Kommentaren zu der Frage geht hervor, dass es sich um eine Regression in g ++ 9 handelt, die auf Gentoo gemeldet wurde: bugs.gentoo.org/701364
Keith Thompson