Is the return statement valid for constexpr constructors?

As explained in this page , the constexpr compound body operator, if it is not removed or not installed by default, must satisfy the constexpr function body constexpr , that is, it can contain any statements except:

  • ad asm
  • a goto statement
  • a try -block
  • definition of a variable of non-literal type or static or duration of storage of flows or for which initialization is not performed

It seems that the standard does not limit the number of return that may appear, while in C ++ 11 only one is allowed.

Now consider the following code:

 class Thing { public: // Shouldn't this constructor be fine under both C++11 and C++14? constexpr Thing ( ) { return; } }; int main ( ) { Thing a_nice_thing; } 

Clang (3.5 with -std = C ++ 14) compiles it in order, but GCC (4.9.1 with -std = C ++ 14) does not complain:

Constexpr constructor has no empty body

However, if it is modified:

 class Thing { public: // This constructor is fine under both C++11 and C++14 constexpr Thing ( ) { static_assert( __cplusplus > 1 , "static_assert isn't the right mechanism to test this, since it wasn't available at earlier versions of the language" ); } }; int main ( ) { Thing a_nice_thing; } 

Then it compiles under both compilers.

Since the GCC complains that the constructor body is not empty, should it also complain in a later case? Is this behavior a bug in GCC? Is the return statement valid for constexpr constructors?

Note: whether a single return really worth it is not a question of this question, although it is interesting and maybe worth another. I put single return into constructors whose body is empty, for style reasons.

+6
source share
2 answers

GCC does not currently support the C ++ 14 constexpr , so even with -std=c++14 you still get C ++ 11 constexpr .

C ++ 11 limitation for constexpr constructors constexpr (ยง7.1.5 [dcl.constexpr] / p4):

the compound operator of its body-function should contain only

  • null
  • static_assert declaration
  • typedef declarations and declaration aliases that do not define classes or enumerations,
  • using declarations,
  • and use-directives;

(There are many other limitations, I have limited the quote to a link pertaining to the question.)

Operators

return not allowed in constexpr constructors in C ++ 11, and static_assert -.

+5
source

C ++ 14 has changed as described in the draft C ++ 14 . 7.1.5 constexpr specifier

its function body must be = delete, = default or a compound statement that does not contain

- definition of asm,

- goto instruction,

- try block, or

- determination of a non-literal type variable or static or storage duration of streams or for which initialization is not performed

and the constructor must follow additional delimiters:

- either its function body must be = default, or the compound operator of its function body must satisfy the constraints for the body function of the constexpr function;

- each non-invariant non-static data element and sub-object of the base class must be initialized (12.6.2);

- if the class is a union with variant members (9.5), then one of them must be initialized;

- if the class is a unified class, but not a union, for each of its anonymous members of the association having variant members, one of them must be initialized;

- for a constructor without delegation, each constructor selected to initialize non-static data elements and Sub-objects of the base class must be a constexpr constructor;

- for the delegate constructor, the target constructor must be a constexpr constructor.

and this does not interfere with the return or static_assert .

in C ++ 11, it included limitations:

- the compound operator of its body-function should contain only

- zero statements,

- static_assert-declarations

- typedef declarations and declaration aliases that do not define classes or enumerations,

- using-declarations,

- and using directives

which does not allow a return statement.

+1
source

Source: https://habr.com/ru/post/975554/


All Articles