3
votes

I want to reshoot a question based on the answer and appending discussion of:
Why is a non static data member reference not a variable?:

A non-static data member of class doesn't create a new variable itself, it just helps you to define the properties of the class. If it did create a new variable, you'd be able to write code like this:

class Chamber {
public:
    int pot;
};

void f(bool b) {
    if (b)
    Chamber::pot = 2;
}

What would that even mean? Would it find every instance of Chamber and set all their pots to 2? It's a nonsense.


However, in the current n4296 c++17 draft a variable is still definened as (§3.6):

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable’s name, if any, denotes the reference or object.

The argumentation in the accepted answer seems logical to me but it is, based on my understanding of the variable-definition above, conflicting with the standard.

Question Are non-static non-reference data member declarations variables, and if yes, why are they considered to be so since I cannot use them in an intuitive fashion ( as e.g. Chamber::pot from the example in the answer ) ?

2
A declaration of a non-static data member doesn't declare an object, and therefore doesn't introduce a variable.Igor Tandetnik
It does, it is a member subobjectclickMe
Yes they are variables, but without an instance of the class they don't really exist.Some programmer dude
@Someprogrammerdude They can't be variables. If a member declaration is a variable declaration, there must also be exactly one definition ([basic.def.odr]/4). Unless you want to argue that it's a weird kind of variable that is never odr-used (but then in what sense it is an object?)Igor Tandetnik
This is my position: a member declaration doesn't declare an object. An instance of a class object does have subobjects, which can be referred to by a member-access expression that involves a name of a data member - but that doesn't mean that a data member declaration itself declares an object or introduces a variable.Igor Tandetnik

2 Answers

4
votes

No, as Igor Tandetnik pointed out in the comments, non-static data member declarations are never variables, because they are never objects. They are declarations that give the member an object type, but there are no objects until an instance of the class is created.

Quoting Richard Smith:

I suppose the problem is in the ambiguity of what a "declaration of a reference" is. I believe the intent here is that a "declaration of a reference" is a declaration that declares a particular name to be of reference type (which a non-static data member declaration of reference type does), not necessarily a declaration that causes the lifetime of a particular reference to begin. Conversely, a "declaration of an object" is intended to be interpreted as a declaration that declares a particular name to name a specific object (which a non-static data member declaration does not).

That is:

  struct A {
    int &a;
    int b;
  };

'a' is a declaration of a reference, and so we need another condition to restrict it from being a variable. 'b' is /not/ a declaration of an object, so we don't need to say anything further.

Suggestions on how to reword this to make it clearer would be welcome :)

This was followed up as https://github.com/cplusplus/draft/issues/1280, some inconsistencies were found. With some luck, this will be seen as a good opportunity to clear up the standard at the same time.

2
votes

The argumentation in the accepted answer seems logical to me but it is, based on my understanding of the variable-definition above, conflicting with the standard.

There is no conflict with the standard, you've misunderstood the text you quote from §3.6.

A non-static data member is not an object, so it's not a variable either.

An object occupies a region of storage for the duration of its lifetime (see [intro.object]). A non-static data member declaration does not begin the lifetime of some thing that occupies a region of storage. So it doesn't create an object.

When you construct an object of the class' type there will be a sub-object corresponding to the data member, but that subobject is created when the enclosing object is created, and only exists for the object's lifetime. It is not created by the declaration of the data member in the class.

i.e. a subobject for the data member is created when the class object that contains it is created, not when the data member is declared.

So if it's not an object, then it's not a variable.

Question Are non-static non-reference data member declarations variables,

No.