title: Constexpr member function on l-value ref object: Clang and gcc disagree
body: <p>When a class has a constexpr member function and that member function is being evaluated on an l-value object in a constexpr context, clang and gcc disagree whether the result is a constexpr value.
  Why? Is there a workaround that needs neither default-constructability nor copy-constructability?</p>
  
  <p>When the object is passed by value, both compilers succeed compiling.</p>
  
  <p>Clang versions trunk, 8, 7: <code>static_assert expression is not an integral constant expression</code></p>
  
  <p>and</p>
  
  <p>Gcc versions trunk, 8.1, 7.4: compiles with no error</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;array&gt;
  
  using A = std::array&lt;int, 10&gt;;
  
  void foo(const A&amp; a){
      // clang: static_assert expression is not an integral constant expression
      static_assert(a.size() &gt; 0, "");
  }
  
  
  void foo2(A a){
      // this compiles on both clang and gcc
      static_assert(a.size() &gt; 0, "");
  }
  
  // Some custom code with the same symptom:
  class B{
    public:
      constexpr int size()const{
          return 42;
      }
  };
  
  void foo3(const B&amp; b){
      // clang: static_assert expression is not an integral constant expression
      static_assert(b.size() &gt; 0, "");
  }
  
  
  void foo4(B b){
      // this compiles on both clang and gcc
      static_assert(b.size() &gt; 0, "");
  }
  </code></pre>
  
  <p><a href="https://godbolt.org/z/9vmyli" rel="nofollow noreferrer">https://godbolt.org/z/9vmyli</a></p>
  
  <p>Workarounds with caveats:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>void foo5(const B&amp; b){
      // This works in clang, if the default constructor is defined
      static_assert(B().size() &gt; 0, "");
  }
  
  void foo6(const B&amp; b){
      // This works in clang, if the copy constructor is defined
      [](B b){static_assert(b.size() &gt; 0, "");}(b);
  }
  </code></pre>