Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang 3.3 and GCC 4.7 const v's constexpr

I just tried compiling a fairly large body of code using clang 3.3 with GCC 4.7.3 standard library header files on Ubuntu 13.04. This all went well except one issue. This code already compiles with the standard Ubuntu clang 3.2 package on this machine so I'm assuming this is some change in the clang 3.3 compiler. The problem related to const and constexpr using the complex header. In particular the complex type has the following block of code

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 387. std::complex over-encapsulated.
      constexpr double
      real() { return __real__ _M_value; }

      constexpr double
      imag() { return __imag__ _M_value; }
#else
      double&
      real() { return __real__ _M_value; }

      const double&
      real() const { return __real__ _M_value; }

      double&
      imag() { return __imag__ _M_value; }

      const double&
      imag() const { return __imag__ _M_value; }
#endif

In my compile I enter the first block of code and so the compiler sees

constexpr double real() { return __real__ _M_value; }

This results in clang producing an error that the real member function is not const with the following

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/complex:1212:7: 
note: candidate function not viable: 'this' argument has type 'const complex<double>',
      but method is not marked const

      real() { return __real__ _M_value; }

I have read the following post Difference between `constexpr` and `const` and a few other similar documents but am still not really clear if this is a GCC header problem or a clang compiler problem. My feeling is that a member function marked constexpr should be regarded by the compiler as const in which case clang is wrong.

like image 618
goneskiing Avatar asked Jun 21 '13 22:06

goneskiing


1 Answers

According to the status page for clang, N3652 Relaxing requirements on constexpr functions is partially implemented. This paper made a big change. The following passage has been deleted.

A constexpr specifier for a non static member function that is not a constructor declares that member function to be const (9.3.1).

This change means your function cannot be called on const objects anymore. Also, see Fixing constexpr member functions without const which is a proposal to fix those areas of the library.

like image 122
Jesse Good Avatar answered Oct 26 '22 13:10

Jesse Good