Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr non-static member function with non-constexpr constructor (gcc,clang differ)

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.

like image 549
M.M Avatar asked Apr 08 '16 00:04

M.M


People also ask

Does constexpr need to be static?

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?

Can a member function be constexpr?

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.

Why constexpr instead of define?

#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.

Is constexpr always evaluated at compile time?

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.


1 Answers

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

like image 74
user657267 Avatar answered Oct 17 '22 14:10

user657267