C++ Logo


Advanced search

Re: [wg14/wg21 liaison] Allow '.' to behave like '->' where it is currently an error

From: J Decker <d3ck0r_at_[hidden]>
Date: Sun, 1 Mar 2020 22:05:49 -0800
On Fri, Feb 28, 2020 at 8:42 PM Hubert Tong <
hubert.reinterpretcast_at_[hidden]> wrote:

> On Fri, Feb 28, 2020 at 10:25 PM J Decker via Liaison <
> liaison_at_[hidden]> wrote:
>> On Fri, Feb 28, 2020 at 10:07 AM Patrice Roy via Liaison <
>> liaison_at_[hidden]> wrote:
>>> My initial point in response to your message was to point out that in
>>> C++, there are cases where making '.' behave as '->' does today breaks
>>> otherwise correct code and introduces ambiguity.
>>> C++ users, contrary to C# or Java users, have the option of using
>>> objects directly or indirectly. In C# (excluding structs) and Java, all
>>> objects are accessed through indirect means. On the other hand, for a C++
>>> programmer using a smart pointer such as unique_ptr<T>, the ability to
>>> distinguish the services exposed by that object (using '.') and those
>>> exposed by the pointee (using '->') carries meaning, and that distinction
>>> is not readily accessible in some other languages this proposal refers to.
>>> Please also note that operator-> can be (and is sometimes) overloaded in
>>> C++ classes.
>> I'm failing to communicate 'where it is now an error'.
> I think the clarification needs to go beyond that. Using . on a class
> instance where the name to the right does not clearly name a specific
> member is also an error.

I was looking at the C++17 standard...

6.4.5 defines 'class member access' about how the id on the right of -> and
. is looked up... 2)
       For the first option (dot) the first expression shall be a glvalue
having class type.
      For the second option (arrow) the first expression shall be a prvalue
having pointer to class type
     `E1->E2 is converted to the equivalent form (*(E1)).E2;`
     ` the remainder of will address only the first option
(dot).` ...

So what exactly makes the '.' on a 'pointer to class type' generate an
Not having 'class type' but having 'pointer to class type' type?

Pointers, as declared with '*' or created with (&) or as the conversion of
a function or array results in, is just a 'pointer to a ...' , and this
sort of pointer do not have members/properties to access.

There's 3 ways a pointer to a class (not scalar, '.' operator doesn't apply
on pointers to scalar types either) can be used `(*ptr)._id_ `, `ptr[n].
_id_ `, and `ptr->_id_`; the last is converted to the first, array accesses
are also converted to (*(ptr+n))._id_ which leads to '.' as the primary
operator... one operator that cannot, right now, apply to a pointer to a
class is '.' .

I suppose the suggested change would be

if the first expression of (dot) is a pointer, then E1.E2 is converted to
(*(E1)).E2 .

Although I see the potential recursion there

class X ****x; `x.property` could be `(*(*(*(*(x)))).property`
and unique_ptr<X> ***upx; `upx.reset();` could be (*(*(*(upx)))).reset()
and still work...

Maybe reword the above specifying that 'pointer to pointer to...' is still
an invalid type to '.' and only one level of pointer indirection may
apply. ( ' The unary * operator performs indirection:' )

--- other standards sections ...

23.11 Smart Pointers
     .1 1) `A unique pointer is an object that owns another object and
manages that other object through a pointer. More precisely, a unique
pointer is an object u that stores a pointer to a second object p`...

So, a Smart pointer is an object, not a pointer to an object; but clearly
'is an object that owns [a pointer to] another object].
where did 'object' get defined to relate to 'class type' or 'pointer to
class type'....

6.6.1 Memory Model
   3) "A memory location is either an object of scalar type or a maximal
sequence of adjacent bit-fields all having nonzero width "

6.7.2 Compound Types 3) ...' A pointer to objects of type T is referred to
as a “pointer to T '...

  6.4.5 Class member access [basic.lookup.classref]
"1 In a class member access expression (, if the . or -> token is
immediately followed by an identifier followed by a <, the identifier must
be looked up to determine whether the < is the beginning of a template
argument list (17.2) or a less-than operator. The identifier is first
looked up in the class of the object expression. If the identifier is not
found, it is then looked up in the context of the entire postfix-expression
and shall name a class template. "

Received on 2020-03-02 00:08:45