gcc 下指定下标的字符串数组初始化

我执行 echo mem > sys/power/states,系统就可以进入s3,mem是在什么地方定义这个字符串的呢?

在看到linux下面关于电源管理部分的源码时,就明白了,但是刚看到第一段字符串数组的初始化,就感觉怪怪的(可能是自己写代码的时候没有这么用过的原因吧),仔细看了一下,原来是使用了GCC 下的指定下标的数组初始化.

linux/kernel/power/suspend.c

const char *const pm_states[PM_SUSPEND_MACX] = {

#ifdef CONFIG_EARLYSUSPEND

     [PM_SUSPEND_ON]      = "on" ,

#endif

     [PM_SUSPEND_STANDBY]   = "standby" ,

     [PM_SUSPEND_MEM]              = "mem",

};

因为android 下增加了自己的suspend的管理模式, 所以可以去定义支持CONFIG_EARLYSUSPEND。

其中在 linux/include/linux/suspend.h

#define   PM_SUSPEND_ON                   ((__force suspend_state_t )  0)

#define   PM_SUSPEND_STANDBY      ((__force suspend_state_t )  1)

#define   PM_SUSPEND_MEM                ((__force suspend_state_t )  2)

#define   PM_SUSPEND_MAX                 ((__force suspend_state_t )  3)

至此,只想知道gcc对于这种定义方式的定义又是什么呢?

查看gcc 官网看到有如下定义:

https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Designated-Inits.html#Designated-Inits

6.26 Designated Initializers

Standard C90 requires the elements of an initializer to appear in a fixed order, the same as the order of the elements in the array or structure being initialized.

In ISO C99 you can give the elements in any order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C90 mode as well. This extension is not implemented in GNU C++.

To specify an array index, write ‘[index] =’ before the element value. For example,

     int a[6] = { [4] = 29, [2] = 15 };

is equivalent to

     int a[6] = { 0, 0, 15, 0, 29, 0 };

The index values must be constant expressions, even if the array being initialized is automatic.

An alternative syntax for this that has been obsolete since GCC 2.5 but GCC still accepts is to write ‘[index]’ before the element value, with no ‘=’.

To initialize a range of elements to the same value, write ‘[first ...last] =value’. This is a GNU extension. For example,

     int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

If the value in it has side-effects, the side-effects happen only once, not for each initialized field by the range initializer.

Note that the length of the array is the highest value specified plus one.

In a structure initializer, specify the name of a field to initialize with ‘.fieldname =’ before the element value. For example, given the following structure,

     struct point { int x, y; };

the following initialization

     struct point p = { .y = yvalue, .x = xvalue };

is equivalent to

     struct point p = { xvalue, yvalue };

Another syntax that has the same meaning, obsolete since GCC 2.5, is ‘fieldname:’, as shown here:

     struct point p = { y: yvalue, x: xvalue };

Omitted field members are implicitly initialized the same as objects that have static storage duration.

The ‘[index]’ or ‘.fieldname’ is known as adesignator. You can also use a designator (or the obsolete colon syntax) when initializing a union, to specify which element of the union should be used. For example,

     union foo { int i; double d; };
     
     union foo f = { .d = 4 };

converts 4 to a double to store it in the union using the second element. By contrast, casting 4 to typeunion foo stores it into the union as the integeri, since it is an integer. (SeeCast to Union.)

You can combine this technique of naming elements with ordinary C initialization of successive elements. Each initializer element that does not have a designator applies to the next consecutive element of the array or structure. For example,

     int a[6] = { [1] = v1, v2, [4] = v4 };

is equivalent to

     int a[6] = { 0, v1, v2, 0, v4, 0 };

Labeling the elements of an array initializer is especially useful when the indices are characters or belong to anenum type. For example:

     int whitespace[256]
       = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
           ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

You can also write a series of ‘.fieldname’ and ‘[index]’ designators before an ‘=’ to specify a nested subobject to initialize; the list is taken relative to the subobject corresponding to the closest surrounding brace pair. For example, with the ‘struct point’ declaration above:

     struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };

If the same field is initialized multiple times, it has the value from the last initialization. If any such overridden initialization has side-effect, it is unspecified whether the side-effect happens or not. Currently, GCC discards them and issues a warning.

到此时,完全明白了,如何在linux kernel中添加自己想要的电源模式。

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值