Bug 50258 - [C++0x] -std=gnu++0x should allow in-class initialization of static const floating types without constexpr
Summary: [C++0x] -std=gnu++0x should allow in-class initialization of static const flo...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-01 06:29 UTC by Jeffrey Yasskin
Modified: 2011-09-29 19:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-09-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Yasskin 2011-09-01 06:29:30 UTC
In c++98 mode, gcc accepts in-class initialization of static const floating members as an extension. This extension have been removed in C++0x mode, even when gnu extensions are specifically requested with -std=gnu++0x. It would be nice to keep the extension, especially since the C++0x draft was only changed to disallow it in the FDIS.


$ gcc-4.6 --version
gcc-4.6 (GCC) 4.6.1
$ cat test.cc
struct Foo {
  static const double d = 3.14;
};
const double Foo::d;
$ gcc-4.6 -c -Wall test.cc
$ gcc-4.6 -c -Wall -std=gnu++0x test.cc
test.cc:2:27: error: 'constexpr' needed for in-class initialization of static data member 'd' of non-integral type
test.cc:4:19: error: 'const double Foo::d' is not a static member of 'struct Foo'
test.cc:4:14: error: uninitialized const 'Foo::d' [-fpermissive]
$
Comment 1 Jonathan Wakely 2011-09-01 11:51:36 UTC
That extension has been deprecated for years:
http://gcc.gnu.org/onlinedocs/gcc/Deprecated-Features.html
Comment 2 Paolo Carlini 2011-09-23 11:27:49 UTC
Jason, what are we going to do about this? For the record, something like the below would pass the testsuite...

///////////////

Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 179115)
+++ cp/decl.c   (working copy)
@@ -7716,8 +7716,9 @@ check_static_variable_definition (tree decl, tree
   else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       if (literal_type_p (type))
-       error ("%<constexpr%> needed for in-class initialization of static "
-              "data member %q#D of non-integral type", decl);
+       pedwarn (input_location, OPT_pedantic,
+                "%<constexpr%> needed for in-class initialization of static "
+                "data member %q#D of non-integral type %qT", decl, type);
       else
        error ("in-class initialization of static data member %q#D of "
               "non-literal type", decl);
Comment 3 Jonathan Wakely 2011-09-23 12:18:03 UTC
How about using a permerror instead?  Since it's deprecated, requiring users to give -fpermissive if they want to use it in C++11 seems reasonable to me.
Comment 4 Paolo Carlini 2011-09-23 12:45:43 UTC
Of course would work for me.
Comment 5 Jason Merrill 2011-09-23 13:07:33 UTC
permerror sounds good to me.
Comment 6 Paolo Carlini 2011-09-23 13:13:28 UTC
Ok, let me test that + testcase.
Comment 7 paolo@gcc.gnu.org 2011-09-23 16:20:00 UTC
Author: paolo
Date: Fri Sep 23 16:19:52 2011
New Revision: 179121

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=179121
Log:
/cp
2011-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50258
	* decl.c (check_static_variable_definition): Allow in-class
	initialization of static data member of non-integral type in
	permissive mode.

/testsuite
2011-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50258
	* g++.dg/cpp0x/constexpr-static8.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-static8.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Paolo Carlini 2011-09-23 16:22:32 UTC
Done.
Comment 9 Carlos Becker 2011-09-29 10:31:15 UTC
Hello, thanks for taking care of this 'bug'.
I am currently working with ITK (www.itk.org) which doesn't compile with -std=c++0x in gcc 4.6.1 due to this error.

Even though the proposed patch seems to be a proper solution, to me it seems to be that using -fpermissive just to come around this particular error is allowing other non-confirming code to compile as well, which may not be desired in many situations (for instance, assigning a const pointer to a non-const pointer would not be regarded as an error).

In my case, I have modified the patch to throw a warning instead, but probably the best solution would be to add a sort of -fno-constexpr-initialization-check flag. I read that the previous GCC extension is deprecated now, but it is important to take into account that then it would be hard to use c++11 with older code, just because of details like this one.

Thank you.
Comment 10 Jonathan Wakely 2011-09-29 11:49:09 UTC
(In reply to comment #9)
> Even though the proposed patch seems to be a proper solution, to me it seems to
> be that using -fpermissive just to come around this particular error is
> allowing other non-confirming code to compile as well, which may not be desired
> in many situations (for instance, assigning a const pointer to a non-const
> pointer would not be regarded as an error).

Yup. Some compilers allow every single backwards-compatibility feature to be controlled by a separate option. The cost of developing, testing and maintaining that is enormous.

> In my case, I have modified the patch to throw a warning instead, but probably
> the best solution would be to add a sort of -fno-constexpr-initialization-check
> flag. I read that the previous GCC extension is deprecated now, but it is
> important to take into account that then it would be hard to use c++11 with
> older code, just because of details like this one.

That older code wasn't valid in C++03 either, and relied on an extension which was deprecated many years ago.  That sounds like exactly the sort of situation -fpermissive is for.

Rather than changing the effect on this extension, I'd prefer if -fpermissive was changed to reject some truly *ancient* features which haven't been supported without -fpermissive by any version of G++ since 3.0
Comment 11 Carlos Becker 2011-09-29 19:27:39 UTC
Thanks for the quick reply. I understand the implications of having a compiler flag for each deprecated feature, but that would be the best option from the developer's point of view (and obviously not so much from the gcc developer side).

In my case I guess that I will have to patch the headers of the libraries I am using with something like const -> constexpr in the places where I get those errors. -fpermissive is too broad for my taste.

Anyhow I will keep track on this particular 'bug'. Whatever choice is made, it will be important in order to use c++11/0x with older code.