在C

时间:2016-08-02 13:12:35

标签: c arrays gcc

我遇到了以下代码,它以非标准方式在char *中声明C数组:

    /* Message Type description array */ 
    char *msgType[M_LAST_MSG] = 
    {    
       [M_INIT_MSG]     "Init", 
       [M_RESET_MSG]    "Serdes Reset"
    };

M_INIT_MSGM_RESET_MSGM_LAST_MSG是枚举,其对应值为0,1和2。 根据正式的C文档,这个数组中的变量是字符串(文字),那么以这种方式使用这些枚举的目的是什么,是否有任何文档备份它?

使用ARM gcc编译器gcc-arm-none-eabi编译。

2 个答案:

答案 0 :(得分:6)

此语法允许您通过索引初始化数组的特定元素。您可以使用intenum值来指定要初始化的数组元素。这样,您指定的值不需要是连续的。

例如,如果你有这个:

int x[5] = { [2] 3, [4] 7 };

这相当于:

int x[5] = { 0, 0, 3, 0, 7 };

在上面的示例中,枚举值指定数组的元素0和1初始化为"Init""Serdes Reset"

来自C99 standard的第6.7.8节:

  

18每个指定者名单都以其开头描述   当前对象与最近的周围支撑相关联   对。指定符列表中的每个项目(按顺序)指定   它当前对象的一个​​特定成员并改变了   下一个指示符(如果有)的当前对象是该成员。   在指定符列表末尾生成的当前对象是   要由以下初始化程序初始化的子对象。

     

33示例9可以初始化阵列以对应于   使用指示符进行枚举的元素:

enum { member_one, member_two };
const char *nm[] = {
    [member_two] = "member two",
    [member_one] = "member one",
};

编辑:

请注意,标准中的语法包含=,而OP的示例则不包括=。没有head -1 filename | awk -F "\t" '{i=0;med=0;for(i=2;i<=NF;i++) array[i]=$i;asort(array);print length(array)}' 的语法显然是GCC支持的旧语法。编译OP的示例会发出以下警告:

  

警告:过时使用没有'='的指定初始化程序

GCC documentation声明如下:

  

自GCC 2.5以来已经过时的替代语法已经过时,但GCC仍然接受的是在元素值之前写'[index]',没有'='。

答案 1 :(得分:3)

那是GNU extension。它在C99中标准化,语法略有不同,即[index]和值之间的等号,无法指定索引范围。它们被称为指定的初始化器

C标准显示了可能最广泛使用的示例,为枚举提供字符串描述:

  

33示例9 可以使用指示符初始化数组以对应枚举元素:

enum { member_one,           member_two };
const char *nm[] =           {
    [member_two]           = "member two",
    [member_one]           = "member one",
};

它甚至允许像

这样的漂亮东西
  

示例11 当未经修饰的初始化列表可能被误解时,可以使用指示符提供显式初始化:

struct { int a[3], b; } w[] =
    { [0].a = {1}, [1].a[0] = 2 };