[Bug c++/123361] New: False positive "narrowing conversion of 'value' from 'int32_t' {aka 'int'} to 'double'?

dmitriy.ovdienko at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Jan 1 20:50:02 GMT 2026


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).


More information about the Gcc-bugs mailing list