Summary: | Warnings instead of compiler errors for narrowing conversions within list-initializations | ||
---|---|---|---|
Product: | gcc | Reporter: | David Sankel <david> |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED WORKSFORME | ||
Severity: | normal | CC: | antoshkka, jason, manu, marc, nico |
Priority: | P3 | Keywords: | diagnostic |
Version: | 4.7.2 | ||
Target Milestone: | --- | ||
See Also: |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69864 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111723 |
||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | ||
Attachments: | Erroneous C++ 2011 program that has a narrowing conversion error. |
"With -std=c++11, -Wno-narrowing suppresses the diagnostic required by the standard. Note that this does not affect the meaning of well-formed code; narrowing conversions are still considered ill-formed in SFINAE context. " From what I understand, the standard requires the compiler to reject the program, not to accept it with a warning. use -Werror=Wnarrowing then The standard only requires that "a conforming implementation shall issue at least one diagnostic message" so compiling the program with a warning is allowed. As Andrew said, -Werror=narrowing allows you to make it an error if you want. G++ 4.6 gave an error but it was changed to a warning intentionally for 4.7 because many people (myself included) found that narrowing conversions where one of the most commonly encountered problems when trying to compile large C++03 codebases as C++11. Previously well-formed code such as char c[] = { i, 0 }; (where i will only ever be within the range of char) caused errors and had to be changed to char c[] = { (char)i, 0 } (In reply to comment #4) > The standard only requires that "a conforming implementation shall issue at > least one diagnostic message" (This is from 1.4 [intro.compliance] p2) I suppose which gnu extensions are, by default, enabled in the -std=c++11 mode is up for debate (one which I have no interest in). However, this program still compiles with "-pedantic". "-pedantic Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions" Allowing for these narrowing conversions would qualify as a forbidden extension. Regarding compliance, I think Johnathan's snippet is misleading. Here is the relevant surrounding text: If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message. I didn't see in the standard where it states that breaking this feature is "conditionally supported". However, it does say: If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program. Which pretty much allows gcc to do anything it wants with malformed programs. But as stated above, -pedantic should guarentee rejection. I just realized my above comment doesn't make much sense regarding the standard. Please disregard. On the other hand it seems like -pedantic should reject this program, no? Comment 6 misinterprets the standard in multiple ways :) Narrowing conversions do require a diagnostic, but a warning *is* a diagnostic, so G++ is compliant in this regard, this is not a GNU extension. Whether the diagnostic should default to a warning or an error or a "pedwarn" (the category of diagnostic enabled by -pedantic and made into errors by -pedantic-errors) is debatable, but the current behaviour is the result of a conscious decision and is not a bug (certainly not Severity=major) You can use -pedantic-errors to turn this and various other violations from warnings into errors. *** Bug 58986 has been marked as a duplicate of this bug. *** *** Bug 69864 has been marked as a duplicate of this bug. *** Since it seems this has to be explained repeatedly (and I had to read this in detail to understand why this is a pedwarn enabled by -Wall), I created a FAQ: https://gcc.gnu.org/wiki/FAQ#Wnarrowing Jonathan, I used most of your comment #4 verbatim, I hope this is OK. Feel free to edit it for corrections or further clarification. *** Bug 71985 has been marked as a duplicate of this bug. *** *** Bug 71985 has been marked as a duplicate of this bug. *** *** Bug 92856 has been marked as a duplicate of this bug. *** *** Bug 96452 has been marked as a duplicate of this bug. *** |
Created attachment 29023 [details] Erroneous C++ 2011 program that has a narrowing conversion error. Narrowing conversions for initializer lists are producing warnings instead of errors in -std=c++11 mode. See standard 8.5.4 item 3: If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed. and item 7: A narrowing conversion is an implicit conversion... from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly) Compiling the attached program has the following output with -std=c++11: test.cpp: In function ‘void f(double)’: test.cpp:3:26: warning: narrowing conversion of ‘d’ from ‘double’ to ‘float’ inside { } [-Wnarrowing] test.cpp:3:26: warning: narrowing conversion of ‘d’ from ‘double’ to ‘float’ inside { } [-Wnarrowing] test.cpp:3:26: warning: narrowing conversion of ‘d’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]