MSVC and constexpr for function parameter?

  • A+

This code compile fine with clang and gcc.

template<size_t n> struct N {     static constexpr size_t v = n; };  template<size_t n> constexpr bool operator<(N<n>, size_t n2) {     return n < n2; }  template<typename N> constexpr void foo(N v) {     static_assert(v < 5); }  int main() {     foo(N<3>{});     return 0; } 

However, if I use MSVC, I got the error that v < 5 is not a constant expression. I can understand why MSVC thinks that, but I think it is wrong and clang / gcc are right. Is it a bug from MSVC?


If you had declared:

template<size_t n> struct N {   int i;   static constexpr size_t v = n;  }; 

Demo here.

Both MSVC, Clang and GCC would reject your code. The reason is that v is copied into the first parameter of operator<. Such a copy is an evaluation of v and v is not a constant expression.

In your case N is an empty class. I don't think the standard specifies if the copy constructor of such a class should access the memory of the object 1 (core language issue 1701). So the compilers showes a behavior that depends on whether or not the memory of object of empty class is accessed.

Clang and GCC, does not access the memory of object of empty classes when passed has parameters, but MSVC does: see this compiler explorer link

So I think all compilers are right.

1 Accessing the memory representation of the object to copy padding bits would involve a reinterpret_cast (or equivalent) which is also forbiden in constant expression.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: