"reference data member declaration" vs "object data member declaration" and "variables"

99 views
Skip to first unread message

Johannes Schaub

unread,
Dec 17, 2016, 5:48:05 AM12/17/16
to std-dis...@isocpp.org
Hello all. The spec says at 3p6

"A variable is introduced by the declaration of a reference other than
a non-static data member or of an object."

Neither of object and reference data members are variables, so I don't
understand. Why does this paragraph get away with only qualifying the
reference case, but not the object case by "other than a non-static
data member"?

Thanks in advance

Richard Smith

unread,
Dec 18, 2016, 3:44:18 AM12/18/16
to std-dis...@isocpp.org
Because a non-static data member is never an object but might be a reference.

Thanks in advance

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+unsubscribe@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.

Johannes Schaub

unread,
Dec 18, 2016, 11:12:07 AM12/18/16
to std-dis...@isocpp.org
I still don't understand. I can see why a non-static data member is
not the declaration of an object.. because the (sub-) object is only
there once we create an object of the membering class. But how do
references differ in that regard? They too are not "there
immediately", but require an object of the membering class to
necessiate the beginning of the lifetime of a reference for each such
object.

Richard Smith

unread,
Dec 18, 2016, 10:55:49 PM12/18/16
to std-dis...@isocpp.org
On 18 December 2016 at 08:12, 'Johannes Schaub' via ISO C++ Standard - Discussion <std-dis...@isocpp.org> wrote:
I still don't understand. I can see why a non-static data member is
not the declaration of an object.. because the (sub-) object is only
there once we create an object of the membering class. But how do
references differ in that regard? They too are not "there
immediately", but require an object of the membering class to
necessiate the beginning of the lifetime of a reference for each such
object.

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 :)

2016-12-18 9:44 GMT+01:00 Richard Smith <ric...@metafoo.co.uk>:
> On 17 Dec 2016 2:48 am, "'Johannes Schaub' via ISO C++ Standard -
> Discussion" <std-dis...@isocpp.org> wrote:
>
> Hello all. The spec says at 3p6
>
> "A variable is introduced by the declaration of a reference other than
> a non-static data member or of an object."
>
> Neither of object and reference data members are variables, so I don't
> understand. Why does this paragraph get away with only qualifying the
> reference case, but not the object case by "other than a non-static
> data member"?
>
>
> Because a non-static data member is never an object but might be a
> reference.
>

Johannes Schaub

unread,
Dec 19, 2016, 7:28:32 AM12/19/16
to std-dis...@isocpp.org
OK, thanks I see. But, is this intent worded somewhere in the spec
aswell? As far as declarations that contain decl-specifier-seq are
concerned we have at 7p10 that says

"If the decl-specifier-seq contains no typedef specifier, the
declaration is called a function declaration if the type associated
with the name is a function type ([dcl.fct]) and an object declaration
otherwise.".

Am am not totally sure whether this only applies to
simple-declarations (because of the location of that paragraph), or
whether it applies to all declarations that contain
decl-specifier-seqs. Another thing is, because it indicate that an
"object declaration" is not quite the same as a "declaration of an
object", it becomes very involved. Are the following summaries correct
based on your answers and the spec?

struct A {
int &b; // Not the declaration of an object. But an object
declaration. And the declaration of a reference
int c; // Not the declaration of an object. But an object declaration
};

extern int &d; // Not the declaration of an object. But an object
declaration. And the declaration of a reference
int e; // The declaration of an object. And an object declaration.
But not the declaration of a reference

Are they correct concerning the intent? Would it not make sense to
distinguish between object declarations and reference declarations?
Other places in the spec seem to use "object declaration" as implying
that they declare objects, like 7.1.5p9:

"A constexpr specifier used in an object declaration declares the
object as const."

On the other hand, there's evidence that other places use "object
declaration" to mean "declaration that gives names an object or
reference type", such as 8.2p1:

"In that context, the choice is between a function declaration with
a redundant set of parentheses around a parameter name and an object
declaration with a function-style cast as the initializer."

This indicates that this term "object declaration" was not updated
properly when references were added to the language?

Thanks

Richard Smith

unread,
Dec 19, 2016, 1:22:02 PM12/19/16
to std-dis...@isocpp.org
These are some great observations. Can you file an editorial issue with the below content? I'll probably forward some or most of this to cwg to decide on what we want the terms to mean, but we should fix the inconsistency.

(This isn't the only "object" ambiguity we have; "object pointer type" and "pointer to object type" mean different things, as the latter excludes 'cv void*', but at least in that case we have a definition and apply it consistently.)

Reply all
Reply to author
Forward
0 new messages