Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::addressof as a constant expression in C++17

The specification of std::addressof was changed for C++17: it is now allowed to be a constant expression. However, cppreference says that:

The expression std::addressof(E) is a constant subexpression, if E is an lvalue constant subexpression.

  • What is a constant subexpression?
  • What is an example where std::addressof(E) will be a constant expression?
  • What is an example where std::addressof(E) will NOT be a constant expression?
like image 737
Vincent Avatar asked Apr 12 '16 01:04

Vincent


People also ask

What is the constant expression in C++?

A constant value is one that doesn't change. C++ provides two keywords to enable you to express the intent that an object is not intended to be modified, and to enforce that intent. C++ requires constant expressions — expressions that evaluate to a constant — for declarations of: Array bounds.

What is a const expression?

A constant expression is an expression that contains only constants. A constant expression can be evaluated during compilation rather than at run time, and can be used in any place that a constant can occur.


1 Answers

This is explained here.

Introduce the following new definition to the existing list in 17.3 [definitions]: [Drafting note: If LWG 2234 is accepted before this issue, the accepted wording for the new definition should be used instead — end drafting note]

**constant subexpression** [defns.const.subexpr]

an expression whose evaluation as a subexpression of a *conditional-expression* *CE* (5.16 [expr.cond]) would not prevent *CE* from being a core constant expression (5.20 [expr.const]).

So "constant subexpression" roughly means "you can use it in a constant expression".

What is an example where std::addressof(E) will be a constant expression?

I believe it's intended to give a constant expression whenever &E does (assuming that & invokes the built-in address-of operator).

constexpr int x  = 42; // static storage duration
constexpr int* p1 = &x; // x is an lvalue constant subexpression
constexpr int* p2 = std::addressof(x); // x is an lvalue constant subexpression

What is an example where std::addressof(E) will NOT be a constant expression?

std::map<int, int> m;
void f() {
    int& r = m[42];
    constexpr int* z1 = &r; // error: r is not a constant subexpression
    constexpr int* z2 = std::addressof(r); // likewise

    constexpr int x = 43; // automatic storage duration
    constexpr const int y1 = *&x;                // ok; x is a constant subexpression
    constexpr const int y2 = *std::addressof(x); // likewise
    constexpr const int* p1 = &x;                // error: p1 points to an automatic object
    constexpr const int* p2 = std::addressof(x); // likewise

}
like image 182
Brian Bi Avatar answered Sep 20 '22 12:09

Brian Bi