C语言警告warning: missing braces around initializer详解
警告的意思是初始化缺少了大括号,也就是没有用大括号明确的区分出初始化数据的归类。
那什么时候会使用到大括号初始化呢?一般情况下初始化使用到大括号的情况是初始化结构体struct或者数组时。
首先说明一下多维数组和结构体的初始化,下面以二维数组的初始化为例(使用默认值为0):
1、分行初始化:int a[2][3] = {{1,2,3},{4,5,6}}
在{ }内部再用{ }把各行分开,第一对{ }中的初值1,2,3是0行的3个元素的初值。第二对{ }中的初值4,5,6是1行的3个元素的初值。初始化的结果是:
a[0][0]=1;a[0][1]=2;a[0][2]=3;a[1][0]=4;a[1][1]=5;a[1][2]=6;
2、不分行以一个大括号初始化: int a[2][3]={ 1,2,3,4,5,6}
这种初始化时会将{ }中的数据依次赋给a数组各元素(按行赋值)。初始化的结果是:
a[0][0]=1;a[0][1]=2;a[0][2]=3;a[1][0]=4;a[1][1]=5;a[1][2]=6;
3、对部分元素初始化:这里分为两种情况:
a)、使用花括号的分行部分初始化:int a[2 ][3]={{1,2},{4}};这时的初始化结果就是a[0][0]=1;a[0][1]=2;a[0][2]=0;a[1][0]=4;a[1][1]=0;a[1][2]=0;
b)、只使用一个大括号进行部分初始化:int a[2][3] = {1,2,3,5},这时的初始化结果就是a[0][0]=1;a[0][1]=2;a[0][2]=3;a[1][0]=5;a[1][1]=0;a[1][2]=0;
下面说明一下结构体的初始化:
结构体的初始化方式和数组的初始化很类似。一个位于一对大括号内部、由逗号分隔的初始化值列表可用于结构体各成员的初始化。这些值根据结构成员列表的顺序写出。如果初始化列表的值不够,剩余的结构成员将使用默认的值进行初始化。
那这样下来,怎么会出现warning呢?
我们先来回顾一下结构体的定义:结构体时一种将不同类型的数据组合成一个有机整体的聚合数据类型。那么如果结构体中的成员的类型是数组或者结构体时呢?那么这个时候你再仅仅只是用一个大括号来对结构体进行初始化时,就会出现定义不明确的问题了,此外如果对一个多维数组你也只使用一个大括号来进行初始化时,同样也会出现定义不明确的问题。虽说一般编译器会自动将结构中的值按空间顺序依次进行赋值,但是编译器依旧会报一个warning,当然前提是你已经设置了-Wall或者-Wmissing-braces。例如:
struct point
{
int x;
int y;
};
struct line {
struct point start;
struct point end;
};
typedef struct line line;
int main()
{
int array1[2][2] = {11, 12, 13, 14};
int array2[2][2] = {{11, 12}, {13, 14}}; // ok
line l1 = {1, 1, 2, 2};
line l2 = {{2, 2}, {3, 3}}; // ok
return 0;
}
gcc -Wmissing-braces test_missing_braces.c test_missing_braces.c: In function `main':
test_missing_braces.c:19: warning: missing braces around initializer
test_missing_braces.c:19: warning: (near initialization for `array1[0]')
test_missing_braces.c:21: warning: missing braces around initializer
test_missing_braces.c:21: warning: (near initialization for `l1.start')
这里19行出现warning的原因是仅使用了一个大括号来进行初始化,这时编译器会通过自动分行来对每一个元素进行初始化,同理,第21行也是同样的原因。其修正结果分贝为20和22行。
那既然可以自动赋值为什么还报warning呢?这是因为,有时候我们想要的赋值并不是依次赋值的,例如我想array1[1][0]不赋值而array[1][1]=14,如果只使用大括号的情况是:array1[2][2] = {11, 12, 14},结果是array1[1][0]=14,而array1[1][1]=0,这样的结果并不是编程者需要的,所以编译器需要提示你检查对应的地方是否是你需要的或者你需要规范一下代码,来避免这种隐藏的问题或者错误。