Ser*_*gey 5 c++ gcc language-lawyer
让我们编译以下程序:
\n\nint main()\n{\n    uint16_t data = 0;\n    data |= uint16_t(std::round(3.14f));\n    return 0;\n}\n和g++ -Wconversion prog.cpp
我们会得到warning: conversion to \xe2\x80\x98uint16_t {aka short unsigned int}\xe2\x80\x99 from \xe2\x80\x98int\xe2\x80\x99 may alter its value,但我在这里看不到隐式转换。
这种警告应该通过显式强制转换来消除,例如:
\n\ndouble d = 3.14;\nfloat foo1 = d; // Warning\nfloat foo2 = float(d); // No warning\nfloat foo2 = static_cast<float>(d); // No warning\nGCC 就在这里还是一个错误?
\n\n请注意,我的片段很小。例如,在以下情况下警告消失:
\n\nf的后缀3.14,即 make itdouble|=std::roundconst auto r = uint16_t(std::round(3.14f));,然后将其或分配给data。GCC 就在这里还是一个错误?
由于行为与预期不符,我将其称为错误。
来自https://godbolt.org/z/aSj--7,似乎在GCC眼中,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 对前者发出警告,但不对后者发出警告,这不太可能是故意的。因此我认为这是 GCC 维护者的疏忽。
| 归档时间: | 
 | 
| 查看次数: | 4218 次 | 
| 最近记录: |