std::atomic_bool 值的严格转换

Strict conversion of std::atomic_bool values

我有一个包含非常简单的逻辑算术的代码,其中涉及从 std::atomic_bool 编辑的值 return。

#include <iostream>
#include <atomic>

int main() {
    uint16_t v1 = 0x1122;
    uint16_t v2 = 0xaaff;
    std::atomic_bool flag1(false);

    uint16_t r1 = v1 | v2;
    std::cout << std::hex << r1 << std::endl;

    uint16_t r2 = static_cast<uint16_t>(flag1.load()) | static_cast<uint16_t>(0xaaff);
    std::cout << std::hex << r2 << std::endl;

    std::cout << __VERSION__ << std::endl;
}

代码示例是 here。编译行:g++ -std=c++17 -O3 -Wall -pedantic -Wconversion -pthread main.cpp && ./a.out.

基于STD API,load()应该return下划线类型存储在atomic中。所以 flag1.load() 应该 returning bool。但是,编译器发出警告,要求将 int 转换为 uint16_t:

main.cpp:13:55: warning: conversion from 'int' to 'uint16_t' {aka 'short unsigned int'} may change value [-Wconversion]
     uint16_t r2 = static_cast<uint16_t>(flag1.load()) | static_cast<uint16_t>(0xaaff);
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

它究竟在哪里进行这种转换? | 的两边都转换为 uint16_t。为什么它仍然打印警告?

Usual arithmetic conversions(如 ISO 标准第 5 节所述)定义大多数或所有算术和二元运算符的任何操作数在运算本身之前进行整数提升。

这意味着两个 uint16_t 操作数首先提升为 int 以计算按位 | 然后截断回 uint16_t 以存储在 r2.

确实这就是警告的内容:int 被隐式截断为 uint16_t

这些转换还定义了 bool 将始终计算为 1 或 0,因此第一个转换是无用的,但由于第二个操作数将被提升为 int,因此也第二次施法没用,你可以选择

uint16_t r2 = flag.load() | 0xaaff;

并可能通过显式转换为更窄的类型来消除警告,这让您意识到正在发生这种情况:

uint16_t r2 = static_cast<uint16_t>(flag.load() | 0xaaff);