Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Mon, 06 Sep 2021 05:09:48 -0700
Organization: A noiseless patient Spider
Lines: 85
Message-ID: <8635qhx5v7.fsf@linuxsc.com>
References: <867dijb22a.fsf@linuxsc.com> <86a6mt8g69.fsf@linuxsc.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="3555d3b4345d8bc729243ac3d8ab4b79"; logging-data="30354"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+v+2xradM0napZjqJXtKrXqJO6u4RREZo="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:Blv+h0rj8fbqvPxdgiQbVmzmTwU= sha1:zuyIIUa6ymxgjzcZKZoAlPz1mxI=
Xref: csiph.com comp.lang.c:162638
John Bode writes:
> On 7/11/21 2:26 AM, Tim Rentsch wrote:
>
>> John Bode writes:
>>
>>> On 6/24/21 12:33 PM, Tim Rentsch wrote:
>>>
>>>> John Bode writes:
>>>>
>>>> [...]
>>>>
>>>>> To reiterate a point I make a lot - typedef on its own creates
>>>>> leaky abstractions. If I need to know that I have to use the
>>>>> `.` or `->` operator on something, I'd rather have it declared
>>>>> as `struct A foo;` or `struct B *ptr;` instead of a type name
>>>>> that doesn't convey struct-ness at all. Same reason I don't
>>>>> like it when people hide pointers behind typedefs - I once spent
>>>>> half a day chasing my tail because somebody created a typedef
>>>>> name for a pointer type and used that as a template parameter
>>>>> for a vector in C++, such that when I was using an iterator I
>>>>> needed to write
>>>>>
>>>>> (*it)->do_something();
>>>>>
>>>>> However, since the typedef name didn't indicate pointer-ness *at
>>>>> all*, I wound up writing
>>>>>
>>>>> it->do_something();
>>>>>
>>>>> and g++ vomited up hundreds of incomprehensible error messages
>>>>> that basically boiled down to "you need to use a * here, dummy".
>>>>
>>>> Sounds to me like the culprit is C++, not typedefs.
>>>
>>> g++ doesn't handle errors in template parameters very well and
>>> generates a *lot* of hard-to-follow error messages for relatively
>>> simple mistakes. And at the time I was still relatively
>>> inexperienced with C++, which didn't help.
>>>
>>> But the typedef name (or, more properly, the incomplete and leaky
>>> abstraction introduced by that typedef name) was the actual
>>> culprit. [...]
>>
>> I stand by my earlier claim that the culprit here is C++
>> rather than typedefs.
>
> I honestly don't know how to make it any clearer. I lost time due
> to using the wrong syntax. I was using the wrong syntax because the
> information I needed in order to use the right syntax was hidden
> from me. That's not a function of it being C++, that's a function
> of the abstraction not being complete.
You reported a case in a C++ program where confusion of pointer
versus non-pointer generated "hundreds of incomprehensible error
messages", causing you to lose time tracking down the problem.
Consider an analogous case in C:
it.do_something();
with 'it' having the pointer-concealing-typedef'ed type. In gcc
this expression produce a one-line error message:
what.c:7:15: error: 'it' is a pointer; did you mean to use '->'?
and in clang pretty much the same. If we consider a case with a
type that is a pointer to the pointer-concealing-typedef'ed type,
such as:
it->do_something();
where we should have used
(*it)->do_something();
again gcc gives a one-line error message:
what.c:11:15: error: '*it' is a pointer; did you mean to use '->'?
and clang again pretty much the same.
In all of these cases fixing the problem takes perhaps 15 to 30
seconds. By far the larger part of the problem is C++, not any
"hidden" pointerness, which is why I say that the culprit here is
C++ rather than typedefs.