AJ *_*Tan 5 c++ unions constexpr
当我遇到问题时,我正在用工会做一些实验。
union U
{
// struct flag for reverse-initialization of each byte
struct rinit_t { };
constexpr static const rinit_t rinit{};
uint32_t dword;
uint8_t byte[4];
constexpr U() noexcept : dword{} { }
constexpr U(uint32_t x) noexcept : dword{x} { }
constexpr U(uint32_t x, const rinit_t&) noexcept : dword{}
{
U temp{x};
byte[0] = temp.byte[3];
byte[1] = temp.byte[2];
byte[2] = temp.byte[1];
byte[3] = temp.byte[0];
}
};
Run Code Online (Sandbox Code Playgroud)
这是我的示例实例:
constexpr U x{0x12345678, U::rinit};
Run Code Online (Sandbox Code Playgroud)
我在 g++ 的 5.1 和 8.1 版中遇到了这个错误-std=c++14,-std=c++17并且-std=c++2a:
accessing 'U::byte' member instead of initialized 'U::dword' member in constant expression
Run Code Online (Sandbox Code Playgroud)
访问和分配 member 的元素byte,无论是 fromtemp还是this,都会重现错误。似乎byte是由编译器为“未初始化”的成员,即使认可byte和dword共享相同的地址。
我曾经修改过第二个构造函数:
accessing 'U::byte' member instead of initialized 'U::dword' member in constant expression
Run Code Online (Sandbox Code Playgroud)
但是我在最终产生似乎是编译器错误后恢复了:
main.cpp:73:37: internal compiler error: in complete_ctor_at_level_p, at expr.c:5844
constexpr U x{0x12345678, U::rinit};
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://tdm-gcc.tdragon.net/bugs> for instructions.
Run Code Online (Sandbox Code Playgroud)
对于我当前的修复,我添加了一个转换器:
constexpr U(uint32_t x) noexcept :
byte{uint8_t(x), uint8_t(x >> 8), uint8_t(x >> 16), uint8_t(x >> 24)}
{ }
Run Code Online (Sandbox Code Playgroud)
我修改了第三个构造函数:
main.cpp:73:37: internal compiler error: in complete_ctor_at_level_p, at expr.c:5844
constexpr U x{0x12345678, U::rinit};
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://tdm-gcc.tdragon.net/bugs> for instructions.
Run Code Online (Sandbox Code Playgroud)
我只是好奇为什么我会收到错误。谁能帮我理解这个问题?
根据我最近的测试,在constexpr union构造函数中,我不能使用不在初始化列表中的非静态数据成员。因此,我添加了一些struct标志来明确指定某个非静态数据成员的初始化。
// converts the value of a uint32_t to big endian format
constexpr static uint32_t uint32_to_be(uint32_t x)
{
return ( (x >> 24) & 0xFF) |
( (x << 8) & 0xFF0000) |
( (x >> 8) & 0xFF00) |
( (x << 24) & 0xFF000000);
}
Run Code Online (Sandbox Code Playgroud)
有了它,我还为这种初始化添加了新的构造函数。这里有些例子:
constexpr U(uint32_t x, const rinit_t&) noexcept : dword{uint32_to_be(x)} { }
Run Code Online (Sandbox Code Playgroud)
如果有人可以为此提供更好的解决方案,那就太好了。
| 归档时间: |
|
| 查看次数: |
233 次 |
| 最近记录: |