C++20编译出现volatile左操作数复合赋值废弃告警如何解决
C20标准正式弃用了volatile限定类型左值的复合赋值操作,你代码中第185行的num_events_called += event_process(pulse)就是这类操作,所以编译器会抛出告警。volatile关键字的设计初衷是用于内存映射IO、信号处理这类需要禁止编译器优化内存读写的场景,本身不提供多线程原子操作、内存序保证的能力,很多旧项目误将其用于多线程同步,在C20标准下这类误用写法就会触发告警。
根据你使用volatile的实际场景,选择以下任意一种方案即可:
方案1:多线程同步场景(最推荐)
如果你给num_events_called加volatile是为了多线程间读写不出现问题,直接替换为C++标准的原子类型即可:
把变量定义从volatile int num_events_called = 0;修改为
#include <atomic> std::atomic<int> num_events_called = 0;原有第185行的复合赋值代码不需要修改,
std::atomic原生支持复合赋值操作,既没有告警也符合多线程安全要求。方案2:确实需要保留volatile语义的场景
如果这个变量是用于内存映射硬件交互、信号处理等必须保留volatile的场景,把复合赋值拆分为独立的读、计算、写操作即可:
把第185行的num_events_called += event_process (pulse);修改为
num_events_called = num_events_called + event_process(pulse);这种写法保留了
volatile的读写语义,同时不会触发C++20的弃用告警。方案3:不需要volatile语义的场景
如果你确认这个变量不会被非代码逻辑修改、也没有多线程读写需求,直接把变量定义前的volatile关键字删除即可,原有代码不需要其他改动。
不要在多线程同步场景下仅拆分复合赋值表达式:volatile不保证操作的原子性,也不提供内存屏障,即使拆分后没有告警,多线程同时读写依然会出现数据竞争问题,这种场景必须使用std::atomic才符合C++标准要求。
内容的提问来源于stack exchange,提问作者Hardy35

