Lun*_*din 5 c gcc initializer-list
我正在使用gcc 4.9.1/Mingw并使用以下代码编译代码:
gcc test.c -otest.exe -std = c11 -pedantic-errors -Wall -Wextra
此代码提供诊断:
int main (void)
{
char a[5] = {'h','e','l','l','o','\0'};
}
Run Code Online (Sandbox Code Playgroud)
错误:数组初始化器中的多余元素char [5]
但是,此代码不会产生警告:
int main (void)
{
char b[5] = "hello";
}
Run Code Online (Sandbox Code Playgroud)
我认为这两种形式是100%相同的.C标准中是否有任何理由或微妙之处,为什么后者不应该发出警告?
或者这是编译器错误?我知道C标准允许多余的初始化器,与C++不同,所以我不相信gcc 需要进行诊断.但我希望编译器能够始终如一地发出警告.
oua*_*uah 12
而:
char a[5] = {'h','e','l','l','o','\0'};
Run Code Online (Sandbox Code Playgroud)
是无效的.
(C11,6.7.9p2)"没有初始化程序应尝试为未初始化的实体中包含的对象提供值."
这个:
char b[5] = "hello";
Run Code Online (Sandbox Code Playgroud)
C明确允许(强调我的):
(C11,6.7.9p14)"字符类型的数组,可以用字符串初始化字面或UTF-8字符串文字,任选在大括号.字符串常量(的连续字节,包括终止空字符,如果有房间或如果数组的大小未知)初始化数组的元素."
但
char b[5] = "hello!";
Run Code Online (Sandbox Code Playgroud)
是无效的.
这是C标准中一个奇怪的怪癖.回到当天,人们偶尔会使用固定长度的非空终止字符串.(一个例子是V7 Unix中的14个字符的文件名.)因此,为了让这些旧程序继续编译,char使用字符串常量初始化一个显式大小的数组是合法的,最终会刮掉它'\0',就像你刚才那样观测到的.
我同意令人惊讶的是,{'h','e','l','l','o','\0'}初始化器发出警告,而"hello"没有.但这些是两种截然不同的形式,事实证明它们的规则是不同的.当您为阵列提供大小并使用{}表单时,所有初始化程序都必须有空间.但是当你给出一个大小并使用""表格时,对于那种情况和那种情况有一个特殊的例外.
(对于任何一种形式,它在C++中也不合法.)