Is taking the address of a local variable a constant expression in C++11?

前端 未结 6 1286
走了就别回头了
走了就别回头了 2021-02-07 06:13

The following C++11 program:

int x = 42;

void f()
{
        int y = 43;

        static_assert(&x < &y, "foo");
}

int main()
{
        f();         


        
6条回答
  •  一生所求
    2021-02-07 06:21

    Let's try to determine which requirements the expression in the static_assert-declaration has to fulfil step-by-step, using n3485.

    [dcl.dcl]/1

    static_assert-declaration:
    static_assert (constant-expression,string-literal) ;

    [dcl.dcl]/4

    In a static_assert-declaration the constant-expression shall be a constant expression that can be contextually converted to bool.

    [expr.const]/4

    Collectively, literal constant expressions, reference constant expressions, and address constant expressions are called constant expressions.


    So what type of constant expression is &x < &y? It is not an address constant expression:

    [expr.const]/4

    An address constant expression is a prvalue core constant expression (after conversions as required by the context) of type std::nullptr_t or of pointer type [...].

    The type of &x < &y is bool as per [expr.rel]/1.

    It isn't a reference constant expression either, so it must be a literal constant expression, if any.

    A literal constant expression is a prvalue core constant expression of literal type [...]

    Therefore, &x < &y has to fulfil the requirements of a core constant expression.


    As pointed out by TemplateRex and hvd in the comments, in this particular case, &x < &y does not fulfil the requirements of a core constant expression:

    [expr.const]/2

    [a core constant expression must not contain] a relational or equality operator where the result is unspecified;

    [expr.rel]/2

    If two pointers p and q of the same type point to different objects that are not members of the same object or elements of the same array or to different functions, or if only one of them is null, the results of p, p>q, p<=q, and p>=q are unspecified.

    However, for an example like

    int arr[2] = {1, 2};
    static_assert(&a[0] < &a[1], "");
    

    The expression a < a+1 fulfils this requirement as well.

提交回复
热议问题