constexpr int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
The snippet above:
Compiles with no warnings on g++ 7
with -Wall -Wextra -Wpedantic
.
Compiles with no warnings on clang++ 4
with -Wall -Wextra -Wpedantic
.
Fails to compile on MSVC 2017
:
conversion from 'const int' to 'unsigned int' requires a narrowing conversion
Q: is MSVC wrong here?
live example on godbolt.org
int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
Compiles with warnings on g++ 7
with -Wall -Wextra -Wpedantic
:
narrowing conversion of 'i' from 'int' to 'unsigned int'
Fails to compile clang++ 4
with -Wall -Wextra -Wpedantic
:
non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list
Fails to compile on MSVC 2017
:
conversion from 'const int' to 'unsigned int' requires a narrowing conversion
Q: is g++ wrong here? (i.e. should it produce an hard error?)
live example on godbolt.org
There is never a requirement that any C++ program produce a hard error. There are requirements to print diagnostics. The form of the diagnostic is unspecified by the standard: an old joke is that printing out a single space satisifies the diagnostic requirements of the standard. That would be a quality of implementation issue.
There are ill-formed programs upon which the standard places no restrictions on their behavior, and sometimes a mandatory diagnostic.
There are cases where a program is ill-formed and a diagnostic is required. One way to handle that is to produce a message saying it is an error, then do not generate any binary to run. Another way is to produce a message saying it is a warning, then produce a binary that can be run.
So, g++ is not wrong under the standard for merely printing out a warning.
The resulting program is technically all undefined behavior; g++ could format your hard drive when it runs without violating the standard. That would be considered a quality of implementation issue.
Shafik's answer here covers the first question. i
is constant expression and its value fits the target type; there should be no warning or error about the narrowing conversion.
The C++ standard does not defend you against hostile compilers.
Reportedly, -pedantic-errors
can be passed to g++ to have it generate hard errors instead of warnings when the standard mandates the resulting program would be ill-formed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With