[英]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.