C++ Logo

std-proposals

Advanced search

Re: Unify '.' and '->' operator behavior

From: J Decker <d3ck0r_at_[hidden]>
Date: Sat, 15 Feb 2020 20:10:10 -0800
On Sat, Feb 15, 2020 at 7:07 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:

> Hi Jim,
>
> Sadly your idea doesn't work in C++, because C++ has *member functions*.
> That is, we can write things like this:
>
> struct Widget {
> void reset(); // reset the widget
> };
> [...]
> std::unique_ptr<Widget> p = std::make_unique<Widget>();
> p->reset(); // reset the pointed-to widget by calling Widget::reset()
> member function
> p.reset(); // reset the pointer's own value to nullptr
>
>
But, isn't the .reset() implemented on the unique_ptr<> template as a
operator. override? which takes precedence over the default behavior...

 a function member is otherwise the same as any field value, other than
being allocated by the compiler/linker instead of a user value ...
'void f(void);' vs 'void (*pf)(void);' the latter of which can be used in
C structures also.

So -> and . literally have different meanings, and you can't combine them
> in the way you're trying to.
>
> (This would be a good example to show to your C colleagues when they talk
> about . versus -> being a "stumbling block.")
>
> HTH,
> Arthur
>
> On Sat, Feb 15, 2020 at 3:35 PM J Decker via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> I would like to see the operators '.' and '->' inspect their left hand
>> value's type and generate the appropriate base address from it added to C.
>> Since I use C++ compiler often to compile C code as a strongly typed C
>> compiler, this should be suggested here too.
>>
>> See end for additional C++ comments
>> ---
>>
>> My proposal is to make the operator '.' consider the type of the left
>> hand value and behave as '.' or '->' appropriately. I could say, make '.'
>> and '->' equivalent, however, the desire would be to migrate to just using
>> '.' operators and dropping the -> altogether(sometime, in the far future,
>> removal/deprecation is not part of this proposal), since it would become
>> redundant. Maybe it becomes a styling mechanism.
>>
>> This change could be shared with C++ to make sure that c2x(and later)
>> code could still be compiled with C++. C++ Does have operator overloading,
>> but the compiler should be able to determine if the compiler is operating
>> on a structure/union/(class) or a pointer to(array of)
>> struct/union/(class);(see end)
>>
>> In C, in order for either '.' or '->' to be used, the left hand value
>> must be a completely defined structure or union, or a pointer to a
>> structure or union. A pointer to a pointer cannot be used with either of
>> those, requiring some other dereference operation to get down to 1(->) or
>> 0(.) levels of indirection.
>>
>> In either case, the compiler (GCC for instance) has the complete type
>> information of the left hand value, and can inspect whether the value is a
>> reference to a instance of a structure or union, or a pointer to a
>> structure or union. In the first case(instance) the address comes from the
>> local function address space (stack pointer) or some other memory location
>> computed by the compiler, in the second case, the address is given by the
>> value of the left hand value instead of computed by the compiler/linker,
>> and in both cases, the right hand value is a name of a field in a
>> structure/union, which is the additional offset to apply to the base
>> address.
>>
>> The modification to the GCC C compiler (9.x) is nearly trivial. The
>> modification to make '.' and '->' work the same, and to inspect the type of
>> the left hand value and use the 'get variable location' or 'get value of
>> pointer' appropriately. Because of the requirement of a complete type
>> (incomplete types used with '.' or '->' generate an error in all C
>> compilers), every compiler must know the type and it's definition of the
>> left value to use the right hand name in. (the right hand value must be a
>> name within a(the?) structure/union, and cannot be a computed value, ie
>> `ptr->(1+3)` is not valid)
>>
>> This change would have no impact on existing code. Everything that used
>> to compile with a C compiler would continue to compile with a C compiler.
>>
>> Code written against the new standard would potentially not be compatible
>> with previous standards.
>>
>> ---
>> My reasoning for approaching this, or even thinking about it, was from
>> having taken C code which I ported to JS by replacing `TYPE name` with `val
>> name` and '->' to '.', and it was 95% done; other than the function
>> signatures. Taking this code and bringing it back to C becomes and issue
>> because of the loss of -> operators; so I began considering why the implied
>> type information form Javascript wouldn't already exist in the C compiler,
>> since everything must be 'pre-typed', or defined ahead of time with its
>> full type information, that the compiler couldn't also do the 'smart' thing
>> based on the type of the value of the left hand expression.
>>
>> I asked on IRC in ##C and ##programming about this idea, and someone
>> mentioned that the usage of '.' and '->' to programmers just learning the
>> language is very often a stumbling block... since to they do 'the same
>> thing' it's hard to understand why '.' and '->' are even different...
>> Eventually, you understand that they are different because you declared
>> either a 'static' instance of a thing ( FILE a ) vs creating a pointer to a
>> thing ( FILE* pa ).
>>
>> There is the `*` that can dereference a pointer, so you can still use '.'
>> everywhere and never use `->', `(*thing).` ; or `thing[0].` ; however that
>> coding style doesn't improve the ability to back-port C ported to JS back
>> to C. Those mechanisms would still work, since they result in a reference
>> to a structure or union instance instead of the pointer to the same
>> instance.
>>
>> Conversely, it was suggested that losing the distinction of '.' or '->'
>> operators loses information about the types of a thing you are working on.
>> 'pointer->struc.member.something->name' you just 'know' that there is a
>> pointer to a structure that is a single (large) of other structures that
>> has a pointer to a name... so you 'know' it's only 2 memory locations
>> you're dealing with.
>>
>> ---
>> ===
>> C++ notes.
>> This would only apply for the builtin/default handlers for the '.' and
>> '->' operators. Those operator overrides that have been defined by a
>> class/struct should still expect to do their same function. The function
>> of '.' and '->' should still be overloadable with separate handlers;
>> although the C++ code doesn't interact at a compiler level here, and would
>> have no way (?) of generating, 'use base address of structure instance' or
>> 'read value from variable and use as base address of structure'.
>>
>> I've not followed the development and growth of C++ with all the safe
>> pointer extensions... I am far from a deep C++ guru.
>>
>> Jim B
>> https://github.com/d3x0r ( it's pronouced Decker)
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>

Received on 2020-02-15 22:13:01