给出以下用g++ -c test.cpp或g++ -std=c++17 -c test.cpp编译的简化代码
#include <cstddef>
struct sd_bus_vtable {
union {
struct {
size_t element_size;
} start;
struct {
const char *member;
const char *signature;
} signal;
} x;
};
sd_bus_vtable get()
{
return {
.x = {
.signal = {
.member = "",
.signature= "",
}
}
};
}它在GCC 9.2.0和clang 5/6上编译得很好,但在8.3.0或7.4.0上失败,错误消息如下:
test.cpp:25:5: error: could not convert ‘{{{"", ""}}}’ from ‘<brace-enclosed initializer list>’ to ‘sd_bus_vtable’
};为了解决这个问题,函数get()可以更改如下,但是它看起来不太干净.
sd_bus_vtable get()
{
struct sd_bus_vtable t = {
.x = {
.signal = {
.member = "",
.signature= "",
}
}
};
return t;
}问题是,上述代码是否有效?如果是的话,它是否触发了GCC的一些错误,这是在GCC9中修复的?
发布于 2020-02-18 04:07:31
指定的初始化器语法尚未在标准C++中。计划将其包括在C++20中,但尚未定稿或发布。
因此,您依赖于支持这个即将到来的特性的编译器作为扩展。
在已发布的C++标准中,除了第一个标准之外,没有办法为工会成员提供这样的初始化器。(可以在类定义中使用默认的成员初始化程序)。
在此期间,下列代码将起作用:
sd_bus_vtable get()
{
sd_bus_vtable r{};
r.x.signal = {"", ""};
return r;
}注意:此方法(使用赋值操作符切换联合的活动成员)只有在所有的联合成员都有平凡的构造函数和析构函数的情况下才能工作。否则,您需要手动销毁和创建。
另外,可以省略名称x (这称为匿名联合),这样工会成员的名称就可以访问,就好像他们是封闭结构的成员一样。
https://stackoverflow.com/questions/60273556
复制相似问题