如何用非易失性结构初始化易失性结构?

pfa*_*bri 5 c++ struct initialization arduino volatile

背景

我正在尝试创建一个struct. 其中一个不会更改,因此被声明const,但另一个可能会异步更改,因此我想制作它volatile

问题

我正在尝试使用const结构的实例来初始化volatile一个。但是,如果我使用volatile关键字编译器会抛出这个错误:

passing 'volatile rect' as 'this' argument of 'rect& rect::operator=(rect&&)' discards qualifiers [-fpermissive]at line 15 col 8
Run Code Online (Sandbox Code Playgroud)

可重现的例子

#include <Arduino.h>

struct rect {
    int x0;
    int y0;
    int width;
    int height;
};

const    rect outer    = {0, 0, 10, 5};
volatile rect inner;

void setup() {
    inner = {outer.x0 + 1, outer.y0 + 1,
             outer.width - 2, outer.height - 2};
}

void loop() {
    ;
}
Run Code Online (Sandbox Code Playgroud)

省略volatile编译很好:

rect inner = {outer.x0 + 1, outer.y0 + 1,
                            outer.width - 2, outer.height - 2};
Run Code Online (Sandbox Code Playgroud)

一一初始化也可以,但这正是我想要避免的:

inner.x0        = outer.x0 + 1;
inner.y0        = outer.y0 + 1;
inner.width     = 0;
inner.height    = outer.height - 2;
Run Code Online (Sandbox Code Playgroud)

我错过了什么?……可能和这个有关。

小智 2

您错过了错误消息的实际内容。编译器告诉您,要一次性分配整个结构需要一个“复制构造函数”,该构造函数可以理解 volatile 限定符,但实际上并不存在。查看此答案以讨论该错误的含义。

但是,当您一一分配结构的各个元素时,不需要复制构造函数,因此代码可以正常工作。你为什么要“试图避免”这个?

您期望 volatile 限定符做什么?在 C/C++ 中,它阻止编译器优化您的变量或使用它们的代码。而已。

为易失性结构定义库存复制构造函数是没有用的,因为您的并发要求与其他人的并发要求不同。

为了保证结构元素的分配一致,您可能需要禁用中断,如下所示:

cli();
inner.x0        = outer.x0 + 1;
inner.y0        = outer.y0 + 1;
inner.width     = 0;
inner.height    = outer.height - 2;
sei();
Run Code Online (Sandbox Code Playgroud)

但你必须准确分析你需要什么,这偏离了主题。