Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent warning "conversion from 'const unsigned char' to 'const float' requires a narrowing conversion"

Visual C++ 2017 and gcc 5.4 produce conversion from 'const unsigned char' to 'const float' requires a narrowing conversion warning for Line B but not for Line A in this code snippet:

#include <iostream>

int main() {
    const unsigned char p = 13;
    const float         q = p;  // Line A

    std::cout << q << '\n';

    const unsigned char c[3] = {0, 1, 255};
    const float         f[3] = {c[2], c[0], c[1]};  // Line B

    for (auto x:f)
        std::cout << x << '\n';
}

Is this warning valid? Why Line B is treated differently than Line A?

like image 239
Paul Jurczak Avatar asked Apr 25 '18 01:04

Paul Jurczak


1 Answers

The warning is valid, from C++11 narrowing conversions are prohibited in aggregate initialization; but not applied in copy initialization (as before).

If the initializer clause is an expression, implicit conversions are allowed as per copy-initialization, except if they are narrowing (as in list-initialization) (since C++11).

Until C++11, narrowing conversions were permitted in aggregate initialization, but they are no longer allowed.

And

list-initialization limits the allowed implicit conversions by prohibiting the following:

  • conversion from an integer type to a floating-point type, except where the source is a constant expression whose value can be stored exactly in the target type

BTW: c[0], c[1] and c[2] are not constant expressions; you might declare the array as constexpr, i.e. constexpr unsigned char c[3] = {0, 1, 255};. Then exception applied and Line B would work fine too.

like image 118
songyuanyao Avatar answered Nov 03 '22 13:11

songyuanyao