C++ 二元运算符警告

标签 c++ binary bitwise-operators

有人可以解释一些奇怪的警告行为吗?

我知道它隐式转换为整数。 但为什么前两行没问题呢?当使用 ~ 运算符时,编译器开始抛出警告。如果它转换为整数,它不应该在前两行发出警告吗?

Ubuntu 16.04 g++5.4

#include <cstdint>
using namespace std;

// g++ -std=c++11 -Wall -Wconversion main.cpp -o main

// warning: conversion to ‘uint8_t {aka unsigned char}’ from ‘int’ may alter its value [-Wconversion]

int main()
{
    uint8_t a = 0x00U;
    uint8_t b = 0x01U;

    a = a | b;  // no warning
    a |= b;     // no warning
    a = ~b;     // warning
    a = a | ~b; // warning
    a |= ~b;    // warning
    return 0;
}

最佳答案

当算术表达式中涉及小于int的变量或值时,对于int来说是implicitly converted。对于某些类型,编译器可以执行另一个隐式转换回原始类型,但在其他类型中,在不丢失数据的情况下这是不可能的。

以无符号字节值 0x00 为例。当转换为 int 时,它变为 0x00000000。按位补码会将其转换为 0xffffffff,而无法在不丢失数据的情况下将其转换回无符号字节。

对于这样的值来说尤其糟糕,因为作为 int0xffffffff 等于 -1(读取 two's complement 到了解原因),它实际上无法干净地转换为无符号字节。

因此,为了避免溢出的风险(除非需要),我建议您使用 int (或 unsigned int)进行所有整数算术。然后,除非绝对需要,否则不要转换为较小的类型。

关于C++ 二元运算符警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51302646/

相关文章:

c++ - std::cin.getline() 与 std::cin

c - openssl ssl_read 将读取的二进制数据发送到 char*

java - 二进制长除法算法

javascript - 在 TypeScript 中转换 FlaggedEnum

c++ - 而在std::cout , what does it work for?之前使用左移运算符(<<)

c++ - 在模板参数中使用静态 constexpr 成员数组作为指针

c++ - 应对 C++11 初始化语法

c++ - 你能给我一个 16 位(或更多)十进制数,它只在第 15 位正确转换为 double float 吗?

linux - 分发静态链接的 ELF 32 位二进制文​​件 - 它会在所有平台上运行吗?

c++ - 是否可以重载索引运算符 [] 以从整数返回位?