【问题标题】:Using non standard declaration of array in C在 C 中使用非标准数组声明
【发布时间】:2016-12-07 20:47:35
【问题描述】:

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

    /* 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

【问题讨论】:

  • 您可能在初始化中缺少=[M_INIT_MSG] = "Init" 等。搜索指定初始化程序
  • 不,我没有错过。答案已编辑。
  • 谈论标准/非标准然后链接到 gcc 扩展可能不是一个好主意...但是链接页面中的内容不清楚?它是一个过时的 gcc 扩展,你读过这个页面吗?来自页面:“自 GCC 2.5 以来已过时但 GCC 仍然接受的另一种语法是在元素值之前写 '[index]',没有 '='。”跨度>
  • 是的,我读过了,谢谢。这解释了我的问题。

标签: c arrays gcc


【解决方案1】:

此语法允许您按索引初始化数组的特定元素。您可以使用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 的示例中没有。没有= 的语法显然是GCC 支持的旧语法。编译 OP 的示例给出以下警告:

警告:过时使用不带“=”的指定初始化程序

GCC documentation 声明如下:

自 GCC 2.5 以来已过时但 GCC 仍然接受的另一种语法是在元素值之前写“[index]”,不带“=”。

【讨论】:

  • 不带等号的语法是 GNU 特定的。
  • 这不能回答为什么问题中的语法有效。 OP 显然知道标准语法。
【解决方案2】:

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

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 };

【讨论】:

  • 介意链接到文档吗?
  • @CinCout, C11 draft 6.7.9 Initialization
  • 我错过了缺少等号。我修改了答案。
猜你喜欢
  • 2023-03-11
  • 2014-08-25
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多