为什么gcc允许char数组初始化,字符串文字比数组大?

Ash*_*ppa 17 c c++ arrays compiler-errors string-literals

int main()
{
    char a[7] = "Network";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C中的字符串文字在内部以nul字符终止.因此,上面的代码应该给出编译错误,因为字符串文字的实际长度Network是8并且它不能适合char[7]数组.

但是,Ubuntu上的gcc(即使有-Wall)编译此代码时没有任何错误或警告.为什么gcc允许这样做而不将其标记为编译错误?

当char数组大小小于字符串文字时,gcc只发出警告(仍然没有错误!).例如,它警告:

char a[6] = "Network";
Run Code Online (Sandbox Code Playgroud)

[相关] Visual C++ 2012给出了一个编译错误char a[7]:

1>d:\main.cpp(3): error C2117: 'a' : array bounds overflow
1> d:\main.cpp(3) : see declaration of 'a'
Run Code Online (Sandbox Code Playgroud)

unw*_*ind 26

使用大于它的字符串文字初始化char数组在C中很好,但在C++中是错误的.这解释了gcc和VC++之间的行为差​​异.

如果使用VC++编译相同的C文件,则不会出错.如果您使用g ++将其编译为C++文件,则会出错.

C标准说:

字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来.字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素.

[...]

例8

声明

char s[] = "abc", t[3] = "abc";
Run Code Online (Sandbox Code Playgroud)

定义''plain''char数组对象s,t其元素用字符串文字初始化.该声明与之相同

char s[] = { 'a', 'b', 'c', '\0' },
     t[] = { 'a', 'b', 'c' };
Run Code Online (Sandbox Code Playgroud)

(C11标准草案第6.7.9节,最终标准中的实际措辞可能有所不同.)

这意味着如果阵列没有空间,则丢弃终止字符是完全正确的.这可能是意料之外的,但它正是语言应该如何工作,以及(至少对我来说)众所周知的特征.

相反,C++标准说:

没有比数组元素更多的初始化器.

例:

 char cv[4] = "asdf"; // error
Run Code Online (Sandbox Code Playgroud)

由于隐含的尾随'\ 0'没有空格,因此格式错误.

(C++ 2011草案n3242的 8.5.2 .)

  • @Ashwin 不确定 Visual Studio,也许它正在编译为 C++,其规则*可能*不同?不,这不安全,因为“strlen()”需要一个正确的以 0 结尾的字符串。 (2认同)