[英]Aggregate initialization of anonymous struct with designated initializers
我正在移植旧版 C++ 代码以使用 GCC 9.2。 使用 C++20 和 GNU 扩展是有效的选项。
遗留代码大量使用嵌套在联合中的匿名结构和具有指定初始化的聚合初始化,例如:
union u
{
int a;
struct
{
int b;
int c;
};
};
u f = { .b = 1, .c = 2 };
此示例使用clang -std=gnu++2a -Wall -Wextra
进行编译,但无法使用g++ -std=gnu++2a -Wall -Wextra
:
错误:“u”的初始化程序太多
由于在代码中应用此类结构的情况很多,因此有必要以自动方式(例如在正则表达式的帮助下)对代码应用潜在的更改。 如何通过以自动化方式尽可能少地更改代码来使用 GCC 9.2 编译“此代码”?
通过将嵌套结构移动到联合中的第一个 position 并像非匿名结构一样初始化结构,使用g++ -std=gnu++2a -Wall -Wextra
:
union u {
struct
{
int b;
int c;
};
int a;
};
u f = { {.b = 1, .c = 2 } };
应该可以使用union
定义中的正则表达式检测union
中的所有匿名struct
。 但是我看不到如何使用正则表达式来适当地修改列表初始化。
您只能初始化联合的一个成员:
因为 15.6.2 [class.base.init] 第 8 段:尝试初始化联合的多个非静态数据成员会导致程序格式错误。
因此,如果您输入: {.b=1, .c=2 }
它会看到您正在初始化两个成员。
然后您可以初始化.b
或.c
但不能同时初始化。
而且:
如果元素是匿名联合 object 并且初始化器列表是指定初始化器列表,则匿名联合 object 由指定初始化器列表{D}初始化,其中 D 是指定初始化器子句,命名匿名联合 object。 应该只有一个这样的指定初始化子句。
关键是:其中 D 是命名匿名联合 object成员的指定初始化子句
您可能会在此处获得更多信息。
为了能够给struct
的成员一个值,你应该给一个元素:
union u
{
int a;
struct
{
int b;
int c;
} v; // <-- this
};
u f = { .v = { .b = 1, .c = 2 } };
但这会破坏对每个u
的访问:即fvb = 0
。
所以我认为你的构造与 C++20 不兼容。 为什么 clang 编译和工作? 当不涉及构造函数和/或析构函数时,它可能是一个扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.