title: Using constexpr wrong from the c++11 standard or have I caught some compiler bug?
body: <p>I'm playing with the constexpr keyword and coded the following simple program:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  using namespace std;
  
  template&lt;typename T&gt;
  constexpr bool is_equal(T const* array1, T const* array2, size_t len)
  {
      return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] &amp;&amp; is_equal&lt;T&gt;(array1, array2, len - 1) : true);
  }
  
  template&lt;typename T, size_t N1, size_t N2&gt;
  constexpr bool is_equal(T const (&amp;array1)[N1], T const (&amp;array2)[N2])
  {
      return N1 == N2 &amp;&amp; is_equal&lt;T&gt;(array1, array2, N1);
  }
  
  
  
  template&lt;typename T, size_t N&gt;
  constexpr size_t arraylength(T const (&amp;array)[N])
  {
      return N;
  }
  
  
  
  constexpr size_t stringlength(char const* str, size_t len=0)
  {
      return str ? (*str ? stringlength(str + 1, len + 1) : len) : 0;
  }
  
  
  
  constexpr size_t min(size_t one, size_t another)
  {
      return one &lt; another ? one : another;
  }
  
  
  
  constexpr size_t min_length(char const* str1, char const* str2)
  {
      return min(stringlength(str1), stringlength(str2));
  }
  
  
  
  template&lt;typename T, size_t N1, size_t N2&gt;
  constexpr size_t min_length(T const (&amp;array1)[N1], T const (&amp;array2)[N2])
  {
      return min(N1, N2);
  }
  
  
  
  template&lt;bool cond=false&gt;
  struct to_num
  {
      enum {value=0};
  };
  
  template&lt;&gt;
  struct to_num&lt;true&gt;
  {
      enum {value=42};
  };
  
  
  
  template&lt;size_t init&gt;
  struct two_times
  {
      enum {value=init*2};
  };
  
  
  
  static constexpr char x[]{"One string"};
  static constexpr char y[]{"One string"};
  
  static constexpr int a[]{1,2,3,4};
  static constexpr int b[]{1,2,3,4};
  
  static constexpr int const* const c = &amp;a[0];
  static constexpr int const* const d = &amp;b[0];
  
  int main()
  {
      cout &lt;&lt; "The two literals are equal: " &lt;&lt; to_num&lt; is_equal("One string", "One string") &gt;::value &lt;&lt; endl; // COMPILES AND WORKS IN GCC BUT NOT IN CLANG
      cout &lt;&lt; "The two variables x &amp; y are equal: " &lt;&lt; to_num&lt; is_equal(x, y) &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "Pointers a &amp; c are equal: " &lt;&lt; to_num&lt; a == c &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "Pointers b &amp; c are equal: " &lt;&lt; to_num&lt; b == c &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "Pointers c &amp; d are equal: " &lt;&lt; to_num&lt; c == d &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "The contents of c &amp; d is the same: " &lt;&lt; to_num&lt; is_equal(c, d, arraylength(a)) &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "Pointers a &amp; b are equal: " &lt;&lt; to_num&lt; a == b &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "The contents of a &amp; b is the same: " &lt;&lt; to_num&lt; is_equal(a, b) &gt;::value &lt;&lt; endl;
      cout &lt;&lt; "String x contains " &lt;&lt; two_times&lt; stringlength(x) &gt;::value / 2 &lt;&lt; " characters" &lt;&lt; endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
      cout &lt;&lt; "String literal contains " &lt;&lt; two_times&lt; stringlength("literal") &gt;::value / 2 &lt;&lt; " characters" &lt;&lt; endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
      cout &lt;&lt; "Array literal contains " &lt;&lt; two_times&lt; arraylength("literal") &gt;::value / 2 &lt;&lt; " values" &lt;&lt; endl;
      return 0;
  }
  </code></pre>
  
  <p>As the comments remark, some code compiles and works ok with g++ but not with clang++ and other compiles and work ok with clang++ but not with g++</p>
  
  <p>The gcc error is:</p>
  
  <pre><code>comaprison.cpp: In function ‘int main()’:
  comaprison.cpp:97:62:   in constexpr expansion of ‘stringlength(((const char*)(&amp; x)), 0ul)’
  comaprison.cpp:29:55:   in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
  comaprison.cpp:97:64: error: ‘((((const char*)(&amp; x)) + 1u) != 0u)’ is not a constant expression
       cout &lt;&lt; "String x contains " &lt;&lt; two_times&lt; stringlength(x) &gt;::value / 2 &lt;&lt; " characters" &lt;&lt; endl;
                                                                  ^
  comaprison.cpp:97:64: note: in template argument for type ‘long unsigned int’ 
  comaprison.cpp:98:76:   in constexpr expansion of ‘stringlength(((const char*)"literal"), 0ul)’
  comaprison.cpp:29:55:   in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
  comaprison.cpp:98:78: error: ‘((((const char*)"literal") + 1u) != 0u)’ is not a constant expression
       cout &lt;&lt; "String literal contains " &lt;&lt; two_times&lt; stringlength("literal") &gt;::value / 2 &lt;&lt; " characters" &lt;&lt; endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
                                                                                ^
  comaprison.cpp:98:78: note: in template argument for type ‘long unsigned int’ 
  </code></pre>
  
  <p>and the clang++ one is:</p>
  
  <pre><code>comaprison.cpp:89:55: error: non-type template argument is not a constant expression
      cout &lt;&lt; "The two literals are equal: " &lt;&lt; to_num&lt; is_equal("One string", "One string") &gt;::value &lt;&lt; ...
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  comaprison.cpp:8:19: note: subexpression not valid in a constant expression
      return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] &amp;&amp; is_equal&lt;T&gt;(array1, array2...
                    ^
  comaprison.cpp:14:24: note: in call to 'is_equal(&amp;"One string"[0], &amp;"One string"[0], 11)'
      return N1 == N2 &amp;&amp; is_equal&lt;T&gt;(array1, array2, N1);
                         ^
  comaprison.cpp:89:55: note: in call to 'is_equal("One string", "One string")'
      cout &lt;&lt; "The two literals are equal: " &lt;&lt; to_num&lt; is_equal("One string", "One string") &gt;::value &lt;&lt; ...
                                                        ^
  1 error generated.
  </code></pre>
  
  <p>g++ is "gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)",
  clang++ is "Ubuntu clang version 3.4-1ubuntu1 (trunk) (based on LLVM 3.4)"</p>
  
  <p>Both in a x86_64 linux.</p>
  
  <p>The command lines are:</p>
  
  <pre><code>clang++ -std=c++11 -o comaprison comaprison.cpp
  g++ -std=c++11 -o comaprison comaprison.cpp
  </code></pre>
  
  <p>So, am I doing anything outside the c++11 standard with this code or there is something wrong in both compilers?.</p>
  
  <p>Note that If I remove the g++ problematic lines but leave the clang++ problematic one, the code compiles and works with g++ and if I remove the clang++ problematic line and leave the g++ problematic ones, the code compiles and works ok with clang++</p>
  
  <p>Note also that I'm using the two templated structs to force the compiler to resolve the functions at compile time.</p>
  
  <p>Thank you for your time and experience.</p>