为什么多维数组中的空字符串文字会衰减为空指针?

Why does an empty string literal in a multidimensional array decay to a null pointer?

我想定义一个多维 C 字符串数组,由几个字符串文字初始化。在 C 中,我会执行以下操作:

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

使用 gcc -std=c18 -pedantic test.c 编译并执行结果:

$ ./a.out 
0x55d95410f004  0x55d95410f008

如我所料,strArr[1][0] 中的空字符串文字衰减为有效指针。


但是,当我在 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;
}

使用 g++ -std=c++17 -pedantic test.cpp 编译并执行结果:

$ ./a.out 
0x55c61494d004  (nil)

此处,strArr[1][0] 中的空字符串文字衰减为空指针。 为什么在 C++ 中会发生这种情况?


在 C++17 标准中,我在 5.13.5 第 16 段中看到以下内容:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (6.7).

这似乎表明一个空字符串文字,作为一个普通的字符串文字,应该有静态存储持续时间。那么为什么空字符串文字会衰减为空指针?

没有这样的衰退;您观察到的输出是一个编译器错误。

(是的,这是一个简短的回答,但没有其他要补充的)。

这种行为是不正确的,在这种情况下是 GCC 回归的结果:https://gcc.gnu.org/PR90947

GCC 版本 9.3 的回归已得到修复,并且应该有望恢复到受影响的早期版本。