https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123361

            Bug ID: 123361
           Summary: False positive "narrowing conversion of 'value' from
                    'int32_t' {aka 'int'} to 'double'?
           Product: gcc
           Version: 13.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dmitriy.ovdienko at gmail dot com
  Target Milestone: ---

Following code if compiled with the `-Werror=narrowing` key emits the warning
which does not make sense for me:

```cpp
#include <cstdint>

struct X
{
  double d;

  X(int32_t value) : d{value} {}
  X(int16_t value) : d{value} {}
  X(int8_t value) : d{value} {}
};
```

$ g++ -Werror=narrowing ./2.cpp
./2.cpp: In constructor ‘X::X(int32_t)’:
./2.cpp:7:24: error: narrowing conversion of ‘value’ from ‘int32_t’ {aka ‘int’}
to ‘double’ [-Werror=narrowing]
    7 |   X(int32_t value) : d{value} {}
      |                        ^~~~~
./2.cpp: In constructor ‘X::X(int16_t)’:
./2.cpp:8:24: error: narrowing conversion of ‘value’ from ‘int16_t’ {aka ‘short
int’} to ‘double’ [-Werror=narrowing]
    8 |   X(int16_t value) : d{value} {}
      |                        ^~~~~
./2.cpp: In constructor ‘X::X(int8_t)’:
./2.cpp:9:23: error: narrowing conversion of ‘value’ from ‘int8_t’ {aka ‘signed
char’} to ‘double’ [-Werror=narrowing]
    9 |   X(int8_t value) : d{value} {}
      |                       ^~~~~

This case is similar to the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49793.
However the Standard there IMHO is interpreted incorrectly:

>  8.5.4/7: 

> A narrowing conversion is an implicit conversion
> ...
> * from an integer type or unscoped enumeration type to a floating-point type, 
> except where the source is a constant expression and the actual value after 
> conversion will fit into the target type and will produce the original value 
> when converted back to the original type, or ....

It seems "integer" means any integer ((u)int64, (u)int32, (u)int16, etc). And
indeed we cannot convert any `int64` value into `double` without the data loss.
However int32/16/8 can be converted into double as double has 52 bits for the
mantissa (m*2^e).

Reply via email to