C++ GCC和-Wconversion
让我们编译以下程序:C++ GCC和-Wconversion,c++,gcc,language-lawyer,C++,Gcc,Language Lawyer,让我们编译以下程序: int main() { uint16_t data = 0; data |= uint16_t(std::round(3.14f)); return 0; } 使用g++-Wconversion prog.cpp 我们将得到警告:从'int'转换为'uint16_t{aka short unsigned int}可能会改变其值,但我在这里看不到隐式转换 此类警告应通过显式强制转换静音,例如: double d = 3.14; float foo1
int main()
{
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
return 0;
}
使用g++-Wconversion prog.cpp
我们将得到警告:从'int'转换为'uint16_t{aka short unsigned int}可能会改变其值
,但我在这里看不到隐式转换
此类警告应通过显式强制转换静音,例如:
double d = 3.14;
float foo1 = d; // Warning
float foo2 = float(d); // No warning
float foo2 = static_cast<float>(d); // No warning
double d=3.14;
float foo1=d;//警告
浮点数foo2=浮点数(d);//没有警告
float foo2=静态_cast(d);//没有警告
GCC就在这里还是一个bug
请注意,我的代码片段是最小的。例如,警告在以下情况下消失:
- 从
中删除3.14
后缀,即使其成为f
double
- 使用赋值代替
|=
- 删除
std::round
- 缓存舍入结果:
const auto r=uint16_t(标准::舍入(3.14f))编码>,然后将其分配给
数据
data |=uint16_t(std::round(3.14f))
被翻译为
(无效)(数据=目标,数据非左值)
(TARGET_EXPR
表示一个临时对象。D.2364
是一个内部变量名。)
将GCC内部语言翻译成C++,得到< /P>
data = (temp = (uint16_t) round (3.14e+0), data | temp)
由于逗号表达式的LHS不影响RHS,因此这应该与data=data | temp
一样安全。然而,GCC警告前者,而不是后者,这很可能不是故意的。因此,我认为这是GCC维护人员的疏忽。警告是假的
根据:
对于每一个三元组(L,VQ,R),其中L是一个积分类型,VQ是易变的或空的,R是一个提升的积分类型,存在以下形式的候选算子函数
VQ L& operator|=(VQ L&, R);
因此我们得到一个内置的无符号短运算符|=(无符号短&,无符号int)代码>
给定表达式中没有隐式转换
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
更简单的例子(不需要头和函数)是短数据(0);数据|=短(浮点{3.0f})代码>@VTT确实如此。在我的编译器上复制。