【问题标题】:Why helper macro to fill a struct needs explicit casting? [duplicate]为什么填充结构的辅助宏需要显式转换? [复制]
【发布时间】:2018-01-25 13:17:01
【问题描述】:

考虑一下声明:

struct my_cool_struc {
   int field_x;
   int field_Y;
   int field_z;
};

#define MY_COOL_MACRO(x,y,z) \
  { \
    .field_x = (x), \
    .field_y = (y), \
    .field_z = (z), \
  }

static const struct my_cool_struc why[] = {
  MY_COOL_MACRO(1,2,3),
  MY_COOL_MACRO(6,5,4),
  MY_COOL_MACRO(7,8,9),
  {}
};

static int my_cool_func(...)
{
   struct my_cool_struc p[10];
   int a1, a2, a3;
   unsigned int index = 0;
...
   p[index++] = MY_COOL_MACRO(a1, a2, a3);
...
   return 0;
}

虽然在why 赋值中一切正常,但编译器可以构建函数,但语法解析器失败。

以下解决了这个问题:

- { \
+ (struct my_cool_struc) { \

- p[index++] = MY_COOL_MACRO(a1, a2, a3);
+ p[index++] = (struct my_cool_struc)MY_COOL_MACRO(a1, a2, a3);

编译器是 Linux 上的 GCC(不同版本)。

【问题讨论】:

  • 不是 100% 确定,但我认为您的第二个版本是复合文字 (en.cppreference.com/w/c/language/compound_literal),而第一个版本只是无效代码。
  • 您会遇到语法错误,因为这是分配给结构的无效语法。初始化和赋值是两个非常不同的东西。
  • @SisterFister,第一种情况很好,没有任何错误。
  • @Someprogrammerdude,任何指向文档的指针?此外,问题是为什么第一种情况可以,而第二种情况则失败。在这两种情况下,左值都有定义的类型。
  • 例如{.a = x, .b = y} 不是一个结构,它是一个初始化列表。另一方面,(struct some_struct){.a = x, .b = y} 一个结构,它是一个compound literal。更多信息请参见this C language reference,或read some good books

标签: c macos casting


【解决方案1】:

MY_COOL_MACRO 在声明中使用时,正在使用指定初始化程序,这是一个仅在初始化期间存在的功能。它们不能在分配期间使用。

(struct my_cool_struc)MY_COOL_MACRO 之所以在赋值过程中修复问题,是因为它根本不是演员表。相反,它正在创建一个临时的、未命名的对象,称为复合文字

(struct my_cool_struc){ .field_x = (x), .field_y = (y), .field_z = (z) }

而且由于您正在创建一个对象,{ } 之间的部分是一个初始化器列表,您可以在其中使用指定的初始化器。

然后您在运行时将复合文字分配给您的数组项,这非常好。

【讨论】:

  • 是的,我知道了。我发布的修复(变体 1)如何影响常量 why 的初始化?
  • @0andriy 一点也不,它是多余的,会被优化掉。它与写int x = (int){ 5 }; 而不仅仅是int x = 5; 基本相同。在这种情况下,复合文字不会增加任何内容,并使代码更难阅读。
猜你喜欢
  • 2019-01-06
  • 2021-06-08
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
相关资源
最近更新 更多