代码之家  ›  专栏  ›  技术社区  ›  ilya1725

std::atomic\u bool值的严格转换

  •  0
  • ilya1725  · 技术社区  · 6 年前

    我有一个非常简单的逻辑算术代码,其中包含从 std::atomic_bool .

    #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() 应返回存储在原子中的带下划线的类型。所以 flag1.load() 应该返回 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\u t 。为什么它仍在打印警告?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jack    6 年前

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

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

    实际上,这就是警告的内容:存在对 智力 uint16\u t .

    这些转换还定义了 bool 将始终计算为1或0,因此第一次强制转换无效,但由于第二个操作数将升级为 智力 ,那么第二个演员也没用了,你可以一起去

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

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

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