Bug 54002 - [C++0x] Initializing constexpr static member using constexpr static method fails
Summary: [C++0x] Initializing constexpr static member using constexpr static method fails
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: http://stackoverflow.com/q/11522399/1...
Keywords:
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2012-07-17 19:48 UTC by Martin von Gagern
Modified: 2014-08-29 15:59 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin von Gagern 2012-07-17 19:48:23 UTC
I would expect the following code to work with -std=gnu++0x, but it does not:

class C1 {
  constexpr static int foo(int x) { return x + 1; }
  constexpr static int bar = foo(sizeof(int));
};

g++ 4.5 complains:
error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression

g++ 4.6 and 4.7 complain:
error: field initializer is not constant



Detailed analysis of this problem follows below.

As the function is declared to be constexpr, this surprises me. I took this to Stack Overflow to get some insight:
http://stackoverflow.com/q/11522399/1468366

In his answer http://stackoverflow.com/a/11523155/1468366, Ben Voigt quoted relevant parts from the spec. The most likely cause for this *not* being a constant expression appears to be section 5.19 paragraph 2 item 3:
"an invocation of an undefined constexpr function […]"
qutoed from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

But the definition is there, right in the class. Neither of us could find a part in the specification which might cause the function to not be defined at that point, particularly as the class is completely defined within the initializer, according to section 9.2 paragraph 2.

In case there actually is some part of the spec which makes gccs current behaviour the only correct one, then please consider this report here as a request for a more useful error message, which might make the actual problem known without having to read the specs for hours.

If, on the other hand, the specs allow code like the one above, as I believe they do, then please try to make gcc accept that code as well.
Comment 1 Jonathan Wakely 2012-07-17 20:04:59 UTC
N.B. 4.5 doesn't implement constexpr (it parses the keyword and pretty much ignores it) so that error is irrelevant

I think this might be because C1::foo can't be used in a constant expression until C1 is complete. Jason?
Comment 2 Jonathan Wakely 2012-07-17 20:06:07 UTC
See PR 52366, which makes this a dup of PR 52315
Comment 3 Martin von Gagern 2012-07-18 07:09:02 UTC
(In reply to comment #2)
> See PR 52366, which makes this a dup of PR 52315

I agree that this is a duplicate of PR 52366. And although I'm still not convinced that this is really the same requirement as the one in PR 52315, I'm inclined to believe it nevertheless. Should PR 52366 be un-duped, like PR 52366 comment 4 requested out, then this here should still be duped to PR 52366 instead of PR 52315, so I suggest duping it there in the first place.
Comment 4 Paolo Carlini 2014-08-29 15:54:41 UTC
I'm adding the testcase to the testsuite and closing the bug.
Comment 5 paolo@gcc.gnu.org 2014-08-29 15:58:57 UTC
Author: paolo
Date: Fri Aug 29 15:58:26 2014
New Revision: 214734

URL: https://gcc.gnu.org/viewcvs?rev=214734&root=gcc&view=rev
Log:
2014-08-29  Paolo Carlini  <paolo.carlini@oracle.com>

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

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-54002.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 6 Paolo Carlini 2014-08-29 15:59:23 UTC
Done.