Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I define a constexpr anonymous/unnamed variable?

By mistake, I wrote something along the lines of constexpr bool{};, and while GCC and Clang rejected this, MSVC was more than happy to compile it (see Godbolt). From my understanding, functions (and thus constructors) evaluated at compile time cannot have side effects, therefore this can never have any effect, but is it indeed ill-formed?

(In my experience, MSVC tends to be wrong, but in this specific case I didn’t find where the standard forbids this.)

like image 995
Emma X Avatar asked Dec 03 '19 20:12

Emma X


People also ask

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.

How to declare a constexpr in c++?

A reference may be declared as constexpr when both these conditions are met: The referenced object is initialized by a constant expression, and any implicit conversions invoked during initialization are also constant expressions. All declarations of a constexpr variable or function must have the constexpr specifier.

Where to define constexpr?

constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time.

Can you take the address of a constexpr?

If you need to take the address of constexpr variable, declare it as a static member variable. It can be used as a constant expression this way (as opposed to using a function returning a const).


1 Answers

That's just not valid syntax. It is "forbidden" by the standard by virtue of not being a possible grammar production.

A declaration such as

constexpr bool b{};

is a simple-declaration and has the syntax decl-specifier-seq init-declarator-list(opt) ; (see C++17 [dcl.dcl]/1). The keyword constexpr is a decl-specifier, and so is bool (although only some decl-specifiers have an effect on the type; bool does, but constexpr does not).

The rest of the declaration, b{}, is an init-declarator, which consists of a declarator plus an optional initializer, which in this case is {}. (See [dcl.decl]/1.) The declarator is b. In general, a declarator must contain an identifier such as b. See [dcl.decl]/4.

There is a similar grammar production called an abstract-declarator which lacks an identifier (See [dcl.name]/1). Abstract declarators are allowed in particular contexts, such as when writing down a type-id, or in a parameter-declaration-clause (function parameters are allowed to be unnamed). However, an init-declarator must contain a declarator, not an abstract-declarator.

There is no other grammar production that would match constexpr bool{}; either.

like image 64
Brian Bi Avatar answered Oct 28 '22 18:10

Brian Bi