GCC and -Wconversion
GCC and -Wconversion
让我们编译以下程序:
int main()
{
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
return 0;
}
与g++ -Wconversion prog.cpp
我们会得到warning: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value
,但我在这里看不到隐式转换。
此类警告应通过显式强制转换来静音,例如:
double d = 3.14;
float foo1 = d; // Warning
float foo2 = float(d); // No warning
float foo2 = static_cast<float>(d); // No warning
GCC 就在这里还是一个错误?
请注意,我的代码段很少。例如,在以下情况下,警告将消失:
- 从
3.14
中删除f
后缀,即使其double
- 使用分配而不是
|=
- 删除
std::round
- 缓存舍入结果:
const auto r = uint16_t(std::round(3.14f));
,然后或将其分配给data
。
GCC 就在这里还是一个错误?
由于行为与预期不符,因此我将其称为错误。
从 https://godbolt.org/z/aSj--7 来看,似乎在海湾合作委员会的眼中,data |= uint16_t(std::round(3.14f))
被翻译为
(void) (data = TARGET_EXPR <D.2364, (uint16_t) round (3.1400001049041748046875e+0)>;, data | NON_LVALUE_EXPR <D.2364>;)
( TARGET_EXPR
表示临时对象。 D.2364
是内部变量名称。
将 GCC 的内部语言翻译回 C++,我们将得到
data = (temp = (uint16_t) round (3.14e+0), data | temp)
由于逗号表达式的 LHS 不会影响 RHS,因此这应该与 data = data | temp
一样安全。然而,海湾合作委员会对前者发出警告,但不对后者发出警告,这不太可能是故意的。因此,我认为这是对GCC维护者的疏忽。
警告是假的。
根据[over.built]/22:
对于每个三元组(L,VQ,R),其中L是整型,VQ是易失性或空的,R是提升的整型,存在以下形式的候选算子函数...
VQ L& operator|=(VQ L&, R);
所以我们得到了一个内置unsigned short operator |=(unsigned short&, unsigned int);
给定表达式中没有隐式转换
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- C++ getenv and setenv
- Inference pytorch C++ with alexnet and cv::imread image
- Visual Studio 2019 C++ and std::filesystem
- 保证逻辑 AND 表达式中的函数调用
- python ctypes and C++ pointers
- C++ const char with .begin() and .end()
- Threads with Classes and std::packaged_task
- GCC and -Wconversion