【发布时间】:2022-01-13 07:49:21
【问题描述】:
以下代码使用 gcc 11+ 编译,但使用 gcc 版本
#include <stdint.h>
typedef volatile struct s {
uint32_t receiver:1;
uint32_t transmitter:1;
uint32_t _res:30;
} s_t;
s_t get_struct(void){
struct s m = {0};
return m;
}
int main() {
// compiles using gcc 11
// does not compile using gcc 10 and lower
s_t io1 = get_struct();
return 0;
}
您可以在这里亲自尝试: https://godbolt.org/z/cavYxKdKo
你能解释一下这是为什么吗?
仅供参考,如果单个结构成员使用 volatile 限定(而不是结构本身),则代码将使用早期的 gcc 版本编译。我不知道为什么会这样,因为我认为语义是相同的 (at least they are in C)。
typedef struct s {
volatile uint32_t receiver:1;
volatile uint32_t transmitter:1;
volatile uint32_t _res:30;
} s_t;
类似问题:
【问题讨论】:
-
IIRC
get_struct返回一个s,顶级限定符 (const&volatile) 被忽略。所以s_t io1 = get_struct();尝试从s类型的pr 值初始化volatile s。 -
恕我直言,您要么需要
s的构造函数,要么需要volatile s或const_cast的返回get_struct。 -
如果您将标准设置为 C++17,则使用 gcc 10.x 编译 - 这会强制您进行复制省略。这可能是 gcc 11.x 中的默认设置。
-
@RichardCritten,谢谢,这似乎指向了正确的方向。 ????因此,带有标准 C++14 (
-std=c++14) 的 gcc 11.x 无法编译。但是,我用 gcc 11.x 尝试了-fno-elide-constructors,但确实可以编译。 ???令人费解。无论如何,问题仍然悬而未决,为什么在关闭复制省略时这段代码无法编译?隐式声明的复制构造函数是否与volatile限定符不一致?为什么 C++ 如此神秘? ????♂️ -
-fno-elide-constructors不影响强制复制省略。