5

In N4296, 3.2 [basic.def.odr]p3:

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial 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 is applied to e, or e is a discarded-value expression.

How to explain this paragraph? I found two explanation.

1 from here "Trying to understand [basic.def.odr]/2 in C++14 (N4140)"

Let's split this into steps: The occurrence of a variable `x` in an expression `ex` constitutes an odr-use unless:
  1. Either ex is not potentially evaluated, or
  2. All of the following must be fulfilled:
    1. "applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions" and
    2. "ex is an element of the set of potential results of an expression e" and either of the following holds:
      1. "either the lvalue-to-rvalue conversion is applied to e"
      2. "or e is a discarded-value expression"

and 2 from cppreference http://en.cppreference.com/w/cpp/language/definition

a variable x in a potentially-evaluated expression ex is odr-used unless any of the following is true:

  • applying lvalue-to-rvalue conversion to x yields a constant expression that doesn't invoke non-trivial functions

  • x is an object and ex is one of the potential results of a larger expression e, where that larger expression is either a discarded-value expression or an lvalue-to-rvalue conversion

First answer about two rules is and, the other is any. Which one is right?

Please split rules into steps to explain this code:

struct S { static const int x = 0; };
extern S s;// no definition of s
int i = s.x;// is s odr-used? is x odr-used?
 // gcc 5.1.0 is ok
asked Jul 13, 2015 at 10:58

1 Answer 1

3

cppreference (削除) is (削除ここまで) was wrong; it is clear from the language in the standard (whichever version) that both subclauses must hold. I've corrected it.

In your example, s is not a constant expression (C++14: does not satisfy the requirements for appearing in a constant expression) so is odr-used. The second subclause does not arise.

Meanwhile, x is also odr-used, because although it would be possible to use x in a constant expression in an appropriate context (e.g. as an array bound within the definition of S); x is not one of the potential results of the enclosing expression s.x, which is the only enclosing expression subject to either the discarded-value transformation or the lvalue-to-rvalue conversion.

gcc might be OK without a definition of s or x, but there's no requirement that an implementation diagnose every odr violation.

answered Jul 13, 2015 at 11:17
Sign up to request clarification or add additional context in comments.

3 Comments

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. x is an object so it is a variable.
@dyp sorry, must be a bad day. Of course, this is object vs. reference, not object of class type vs. primitive.
@stackcpp yes, that's correct - by "object" the Standard means object vs. reference, not object of class type vs. primitive.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.