结构体struct初始化多出的点号“.”
在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式,该方式是书中并没有介绍过的。 这种方式称为指定初始化(designated initializer)。
下面我们看一个例子:Linux-2.6.x/drivers/usb/storage/usb.c中有这样一个结构体初始化项目:
static struct usb_driver usb_storage_driver = {
.owner = THIS_MODULE,
.name = "usb-storage",
.probe = storage_probe,
.disconnect = storage_disconnect,
.id_table = storage_usb_ids,
};
乍一看,这与我们之前学过的结构体初始化差距甚远。其实这就是前面所说的指定初始化在Linux设备驱动程序中的一个应用,它源自ISO C99标准。
以下我摘录了C Primer Plus第五版中相关章节的内容,从而就可以很好的理解2.6版内核采用这种方式的优势就在于由此初始化不必严格按照定义时的顺序。
已知一个结构,定义如下
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
1)C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。
例如,只初始化book结构的成员value,可以这样做:
struct book surprise = { .value = 10.99 };
2)可以按照任意的顺序使用指定初始化项目:
struct book gift = { .value = 25.99, .author = "James Broadfool", .title = "Rue for the Toad"};
正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。
3)对特定成员的最后一次赋值是它实际获得的值。
例如,考虑下列声明:
struct book gift = { .value = 18.90, .author = "Philionna pestle", 0.25};
这将把值0.25赋给成员value,因为它在结构声明中紧跟在author成员之后。新的值0.25代替了早先的赋值18.90。 有关designated initializer的进一步信息可以参考c99标准的6.7.8节Ininialization。
4)特定的初始化
标准C89需要初始化语句的元素以固定的顺序出现,和被初始化的数组或结构体中的元素顺序一样。在ISO C99中,你可以按任何顺序给出这些元素,指明它们对应的数组的下标或结构体的成员名,并且GNU C也把这作为C89模式下的一个扩展(这个扩展没有在GNU C++中实现)。为了指定一个数组下标,在元素值的前面写上“[index] = xx”。
比如: int a[6] = { [4] = 29, [2] = 15 };相当于:int a[6] = { 0, 0, 15, 0, 29, 0 };
下标值必须是常量表达式,即使被初始化的数组是自动的。一个可替代这的语法是在元素值前面写上“.[index]”,没有“=”,但从GCC 2.5开始就不再被使用,但GCC仍然接受。 为了把一系列的元素初始化为相同的值,写为“[first ... last] = value”。这是一个GNU扩展。
比如: int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
如果其中的值有副作用,这个副作用将只发生一次,而不是范围内的每次初始化一次。
注意,数组的长度是指定的最大值加一。
以上转载自http://zhouyang340.blog.163.com/blog/static/3024095920123495051607/
数组初始化多出的逗号“,”
在u-boot 2008.10 drivers/net定义的一个结构体如下的初始化
static struct {
const char *name;
u8 version; /* depend on RTL8169 docs */
u32 RxConfigMask; /* should clear the bits supported by this chip */
} rtl_chip_info[] = {
{"RTL-8169", 0x00, 0xff7e1880,},
{"RTL-8169", 0x04, 0xff7e1880,},
{"RTL-8169", 0x00, 0xff7e1880,},
{"RTL-8169s/8110s", 0x02, 0xff7e1880,},
{"RTL-8169s/8110s", 0x04, 0xff7e1880,},
{"RTL-8169sb/8110sb", 0x10, 0xff7e1880,},
{"RTL-8169sc/8110sc", 0x18, 0xff7e1880,},
{"RTL-8168b/8111sb", 0x30, 0xff7e1880,},
{"RTL-8168b/8111sb", 0x38, 0xff7e1880,},
{"RTL-8101e", 0x34, 0xff7e1880,},
{"RTL-8100e", 0x32, 0xff7e1880,},
};
在定义的结构体后面直接进行初始化,关键最后面还多出一个”,“,按理说只有3个成员,why??
先不要着急,请看下面的定义也是在u-boot 2008 10 driver/usb/usbdcore.c
char *usbd_device_states[] = {
"STATE_INIT",
"STATE_CREATED",
"STATE_ATTACHED",
"STATE_POWERED",
"STATE_DEFAULT",
"STATE_ADDRESSED",
"STATE_CONFIGURED",
"STATE_UNKNOWN",
};
看到数组最后也多了个“,” 论坛中也探讨了这个问题