Reputation: 8238
Let's compile the following program:
int main()
{
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
return 0;
}
with g++ -Wconversion prog.cpp
We'll get warning: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value
, but I can't see implicit conversions here.
This kind of warnings should be muted by explicit casts, for example:
double d = 3.14;
float foo1 = d; // Warning
float foo2 = float(d); // No warning
float foo2 = static_cast<float>(d); // No warning
Is GCC right here or it's a bug?
Note that my snippet is minimal. For example, warning disappears in following cases:
f
suffix from 3.14
, i.e. make it double
|=
std::round
const auto r = uint16_t(std::round(3.14f));
, then or-assign it to data
.Upvotes: 5
Views: 5603
Reputation: 85452
The warning is bogus.
According to [over.built]/22:
For every triple (L, VQ, R), where L is an integral type, VQ is either volatile or empty, and R is a promoted integral type, there exist candidate operator functions of the form ...
VQ L& operator|=(VQ L&, R);
So we get a built-in unsigned short operator |=(unsigned short&, unsigned int);
There are no implicit conversions in the given expression
uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
Upvotes: 2
Reputation: 15918
Is GCC right here or it's a bug?
Since the behavior does not match the expectation, I'd call it a bug.
From https://godbolt.org/z/aSj--7, it seems that in GCC's eye, data |= uint16_t(std::round(3.14f))
is translated as
(void) (data = TARGET_EXPR <D.2364, (uint16_t) round (3.1400001049041748046875e+0)>;, data | NON_LVALUE_EXPR <D.2364>;)
(TARGET_EXPR
represents a temporary object. D.2364
is an internal variable name.)
Translate GCC's internal language back to C++, and we'll get
data = (temp = (uint16_t) round (3.14e+0), data | temp)
Since the LHS of the comma expression does not affect the RHS, this should be as safe as data = data | temp
. However, GCC warns at the former but not at the latter, which is very unlikely to be intentional. Thus I believe that it is an oversight of GCC maintainers.
Upvotes: 3