Sergey
Sergey

Reputation: 8238

GCC and -Wconversion

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:

Upvotes: 5

Views: 5603

Answers (2)

rustyx
rustyx

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

cpplearner
cpplearner

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

Related Questions