Bug 55783

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.

Description David Sankel 2012-12-21 23:59:34 UTC
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]
Comment 1 Andrew Pinski 2012-12-22 00:06:50 UTC
"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. "
Comment 2 David Sankel 2012-12-22 00:13:33 UTC
From what I understand, the standard requires the compiler to reject the program, not to accept it with a warning.
Comment 3 Andrew Pinski 2012-12-22 00:15:04 UTC
use -Werror=Wnarrowing then
Comment 4 Jonathan Wakely 2012-12-22 00:26:10 UTC
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 }
Comment 5 Jonathan Wakely 2012-12-22 00:27:51 UTC
(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)
Comment 6 David Sankel 2012-12-22 00:33:44 UTC
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.
Comment 7 David Sankel 2012-12-22 00:42:35 UTC
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 8 Jonathan Wakely 2012-12-22 00:55:31 UTC
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)
Comment 9 Jason Merrill 2013-02-15 17:16:39 UTC
You can use -pedantic-errors to turn this and various other violations from warnings into errors.
Comment 10 Paolo Carlini 2013-11-04 14:47:22 UTC
*** Bug 58986 has been marked as a duplicate of this bug. ***
Comment 11 Manuel López-Ibáñez 2016-02-18 14:04:17 UTC
*** Bug 69864 has been marked as a duplicate of this bug. ***
Comment 12 Manuel López-Ibáñez 2016-02-18 14:20:44 UTC
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.
Comment 13 Markus Trippelsdorf 2016-07-24 12:46:17 UTC
*** Bug 71985 has been marked as a duplicate of this bug. ***
Comment 14 Manuel López-Ibáñez 2016-07-24 15:55:05 UTC
*** Bug 71985 has been marked as a duplicate of this bug. ***
Comment 15 Marc Mutz 2019-12-09 10:28:26 UTC
*** Bug 92856 has been marked as a duplicate of this bug. ***
Comment 16 Andrew Pinski 2021-09-16 21:38:35 UTC
*** Bug 96452 has been marked as a duplicate of this bug. ***