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