When is a variable odr-used in C++14?

后端 未结 1 1552
臣服心动
臣服心动 2020-12-07 23:12

The C++14 draft (N3936) states in §3.2/3:

A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless applying the lva

相关标签:
1条回答
  • 2020-12-07 23:55

    The purpose of odr-use

    Informally, odr-use of a variable means the following:

    If any expression anywhere in the program takes the address of or binds a reference directly to an object, this object must be defined.

    Clarification in the latest draft

    In the latest version of the spec §3.2 has been clarified (see Draft C++14 on GitHub):

    2 An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. The set of potential results of an expression e is defined as follows:

    • If e is an id-expression (5.1.1), the set contains only e.
    • If e is a class member access expression (5.2.5), the set contains the potential results of the object expression.
    • If e is a pointer-to-member expression (5.5) whose second operand is a constant expression, the set contains the potential results of the object expression.
    • If e has the form (e1), the set contains the potential results of e1.
    • If e is a glvalue conditional expression (5.16), the set is the union of the sets of potential results of the second and third operands.
    • If e is a comma expression (5.18), the set contains the potential results of the right operand.
    • Otherwise, the set is empty.

    [ Note: This set is a (possibly-empty) set of id-expressions, each of which is either e or a subexpression of e.

    [ Example: In the following example, the set of potential results of the initializer of n contains the first S::x subexpression, but not the second S::x subexpression.

    struct S { static const int x = 0; };
    const int &f(const int &r);
    int n = b ? (1, S::x) // S::x is not odr-used here
              : f(S::x);  // S::x is odr-used here, so
                          // a definition is required
    

    —end example ] —end note ]

    3 A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any nontrivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression (Clause 5).

    What was the situation in C++11?

    §3.2/2 in C++11 reads:

    An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied.

    The problem with these wordings was DR 712. Consider this example:

    struct S {
      static const int a = 1;
      static const int b = 2;
    };
    int f(bool x) {
      return x ? S::a : S::b;
    }
    

    Since S::a and S::b are lvalues the conditional expression x ? S::a : S::b is also an lvalue. This means that the lvalue-to-rvalue conversion is not immediately applied to S::a and S::b, but to the result of the conditional expression. This means that by the wording of C++11, these static data members are odr-used and a definition is required. But actually only the values are used, hence it is not neccessary to define the static data members - a declaration would suffices. The new wording of draft C++14 solves this.

    Does the new wording resolve all issues?

    No. In the following example the variable S::a is still odr-used:

    struct S { static constexpr int a[2] = {0, 1}; };
    void f() {
        auto x = S::a[0];
    }
    

    Hence I submitted a new issue to add the following bullet to §3.2/2:

    • if e is a glvalue subscripting expression (5.2.1) of the form E1[E2], the set contains the potential results of E1.
    0 讨论(0)
提交回复
热议问题