Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are constexpr objects constructed?

When are constexpr objects constructed relative to non-constexpr non-local objects with static storage duration? Do they start their life prior to initialization of any other objects, i.e., prior to dynamic initialization?

I'm contemplating whether it would be reasonable to have a string_literal class (live example) which is used, e.g., to compare std::strings against certain keywords:

class string_literal
{
    // private members
public:
    constexpr string_literal(char const* b);
    bool operator== (std::string const& other) const;
    bool operator!= (std::string const& other) const;
    // other member functions
};

constexpr string_literal hello("hello");
void f(std::string const& s) {
    if (s == hello) {
        // do something
    }
}

Since the string_literal could parse the string-literal at compile-time to locate the first null-character, I could imagine that these comparisons can be made faster than comparing a std::string against a string-literal. However, to be safe it is necessary that the hello object is readily constructed when the first constructor is executed at run-time during static initialization: otherwise these objects could be accidentally accessed when they are not, yet, constructed.

like image 500
Dietmar Kühl Avatar asked Jan 01 '14 03:01

Dietmar Kühl


People also ask

When can a function be constexpr?

A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.

What does constexpr constructor mean?

A constructor that is declared with a constexpr specifier is a constexpr constructor. Previously, only expressions of built-in types could be valid constant expressions. With constexpr constructors, objects of user-defined types can be included in valid constant expressions.

Where are constexpr variables stored?

A constexpr (or indeed, any kind of variable) need not be stored anywhere if its address is never taken. A constexpr in global or namespace ,when I address it,it should store in .

Where is constexpr defined?

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.


1 Answers

In the C++11 standard the order of initialization of non-local variables is discussed in §3.6.2 “Initialization of non-local variables”.

First static initialization is performed, then dynamic initialization.

Static initialization consists of zero-initialization followed by constant-initialization. Zero-initialization is just what it sounds like. Constant-initialization is new in C++11, and §3.6.2/2 specifies that it's performed

  • if each full-expression (including implicit conversions) that appears in the initializer of a reference with static or thread storage duration is a constant expression (5.19) and the reference is bound to an lvalue designating an object with static storage duration or to a temporary (see 12.2);
  • if an object with static or thread storage duration is initialized by a constructor call, if the constructor is a constexpr constructor, if all constructor arguments are constant expressions (including conversions), and if, after function invocation substitution (7.1.5), every constructor call and full-expression in the mem-initializers and in the brace-or-equal-initializers for non-static data members is a constant expression;
  • if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.

So, the second point is where a constexpr object is potentially initialized, as the last part of static initialization, and essentially it happens if everything is constexpr so that it can be known at compile time.

And yes, as part of the static initialization this happens before dynamic initialization.

like image 92
Cheers and hth. - Alf Avatar answered Oct 16 '22 16:10

Cheers and hth. - Alf