关于标识初始器
关于标识初始器的一些知识点
在阅读 kernel 源码的时候,经常会碰到类似的代码:
1 |
|
好像有点陌生吧,这是什么写法? 这其实是 C99
新增的内容,叫做 designated initializer
,暂且翻译为 标识初始器吧! 在 C90
之前,当你初始化一个数组,结构体或者联合体 (union) 的时候,你必须按照之前定义的顺序来初始化,且中间还不能跳跃。 这在 C99
之后,就已经打破了。
当我们初始化一个数组的时候, C90 之前,我们只能这样初始化:
1 |
|
在 C99
中,你可以用 ‘[index]’
的方式来指定初始化某个元素,其他没有明确初始化的元素,会按照默认值来初始化,所以我们可以这样来做:
1 |
|
就相当于
1 |
|
当我们的数组很大的时候,你还可以这样来初始化:
1 |
|
注意:… 左右需要有空格,否则编译报错 甚至,我们可以和以前的初始化的方式,混合来写:
1 |
|
这里 5
对应于第 3
个元素
而在结构体的初始化中,我们可以这么干: 假如有一个这样的结构体:
1 |
|
当我们初始化它的一个实例的时候,在 C99 中,可以这样来:
1 |
|
注意,顺序和之前定义的是不同的哦,这就相当于:
1 |
|
还有一种写法是这样的:
1 |
|
这是一种老式的写法,在 gcc 2.5
之后,就废弃了,不过,你这么用的话,编译器也不会报错,向后兼容嘛 如果是结构体数组呢,该怎样写?那就混合着来呗:
1 |
|
这是在结构体,在联合体中,照样可以这么用, 假设有这样一个联合体:
1 |
|
在初始化的时候,可以这样做:
1 |
|
说这么多,可能有点迷糊了,那就做一个例子:
1 |
|
用 gcc
编译,可以通过编译,但同时也发现一个问题。 gcc
默认是按照 c89,c90
的标准来编译程序的,
但是这个程序没有加 -std=c99
,也能通过编译, WHY ?
其实虽然标识初始器是 C99
的标准,但是现在的 gcc
已经允许在 c90
的标准中出现这种写法。
实际上,上面提到的那种写法只是 GCC
编译器的一个扩展语法,所以在其他编译器使用的时候可能会报错。所以最好不要使用某类编译器的扩展语法。