严格转换std :: atomic_bool值

时间:2018-05-15 22:57:19

标签: c++11 type-conversion stdatomic

我有一个非常简单的逻辑算法代码,涉及从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_t。为什么还在打印警告?

1 个答案:

答案 0 :(得分:1)

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);