For this code:
struct S
{
S(int m): m(m) {}
constexpr int f() const { return m; }
int m;
};
int main() { S s(1); }
it is compiled with no warnings or errors by clang 3.6, 3.7 and 3.8 with -std=c++14
. But in g++ 5.x the following errors occur:
main.cpp:4:19: error: enclosing class of constexpr non-static member function 'int S::f() const' is not a literal type
constexpr int f() const { return m; }
^
main.cpp:1:8: note: 'S' is not literal because:
struct S
^
main.cpp:1:8: note: 'S' is not an aggregate, does not have a trivial default constructor, and has no constexpr constructor that is not a copy or move constructor
Which compiler is correct and why?
I looked at the requirements in C++14 [dcl.constexpr]/3 which says that for a constexpr
function "each of its parameter types shall be a literal type", but that section does not explicitly mention member functions, and does not say whether the implied *this
counts as a parameter for the purposes of this clause.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later. So, what does constexpr mean?
const can only be used with non-static member functions whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.
#define directives create macro substitution, while constexpr variables are special type of variables. They literally have nothing in common beside the fact that before constexpr (or even const ) variables were available, macros were sometimes used when currently constexpr variable can be used.
constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.
It's a core defect that was fixed for C++14
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684
Clang was patched
https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/6jM8M8FUs30
There's a tracker for GCC but it doesn't look like anyone has addressed it yet
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With