GCC rejects this: constexpr const char * const &r = ""; constexpr const char * const &s = r; with this bogus diagnostic: test.cpp:2:35: error: the value of ‘r’ is not usable in a constant expression constexpr const char * const &s = r; ^ test.cpp:1:31: note: ‘r’ used in its own initializer constexpr const char * const &r = ""; ^
Maybe related: template<typename T> constexpr bool truth(const T&) { return true; } template<typename T> void test() { int i[1]; constexpr bool untrue = !truth(i); static_assert(!untrue, ""); } ce.cc: In function ‘void test()’: ce.cc:8:3: error: non-constant condition for static assertion static_assert(!untrue, ""); ^ ce.cc:8:3: error: the value of ‘untrue’ is not usable in a constant expression ce.cc:7:18: note: ‘untrue’ used in its own initializer constexpr bool untrue = !truth(i); ^
I found another case that worked in G++ 4.8.3 but fails in 4.9: --------- main.cpp: --------- int main () { constexpr int n = 2; A<n> a; B b; b.foo(); } --------- a.hpp: --------- template <size_t n> class A { static constexpr size_t getN() {return n;} }; --------- b.hpp: --------- class B { void foo () { //has access to a A<n> object constexpr int n = a.getN(); A<n> a2; } }; Compiler output: B.hpp: error: the value of ‘n’ is not usable in a constant expression A<n> a2; ^ B.hpp: note: ‘ndims’ used in its own initializer constexpr int n = a.getN(); ^
(In reply to Javier V. Gómez from comment #2) > I found another case that worked in G++ 4.8.3 but fails in 4.9: This example is complete nonsense. Why is it split across three files? Why doesn't main.cpp include anything? Why is everything private? Why is 'a' undeclared in B::foo()? Why does the diagnostic talk about 'ndims' which isn't declared anywhere? It's useless as a test or an example of the error.
(In reply to Jonathan Wakely from comment #3) > (In reply to Javier V. Gómez from comment #2) > > I found another case that worked in G++ 4.8.3 but fails in 4.9: > > This example is complete nonsense. Why is it split across three files? Why > doesn't main.cpp include anything? Why is everything private? Why is 'a' > undeclared in B::foo()? Why does the diagnostic talk about 'ndims' which > isn't declared anywhere? > > It's useless as a test or an example of the error. I tried to simplify as much as possible the issue, since I detected the error in a big piece of code. I didn't pretend to create a compilable example. ndims is what I called n (copy and paste...). The important point of my example is that constexpr int n = a.getN(); fails when A::getN() just returns a template parameter value previously set by a constexpr anywhere else.
This is fixed for 5.0. I'm adding the testcases and closing the bug.
Author: paolo Date: Tue Jan 20 13:39:10 2015 New Revision: 219894 URL: https://gcc.gnu.org/viewcvs?rev=219894&root=gcc&view=rev Log: 2015-01-20 Paolo Carlini <paolo.carlini@oracle.com> PR c++/59937 * g++.dg/cpp0x/constexpr-59937-1.C: New. * g++.dg/cpp0x/constexpr-59937-2.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-59937-1.C trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-59937-2.C Modified: trunk/gcc/testsuite/ChangeLog
Done.