Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #158685

Re: I need help understand a struct

From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: I need help understand a struct
Date 2021-01-28 07:48 -0800
Organization A noiseless patient Spider
Message-ID <86h7n1jc5j.fsf@linuxsc.com> (permalink)
References <ru5b0m$rm6$1@dont-email.me> <478ca6d1-babd-47b4-b9f5-09fba105d9f6n@googlegroups.com> <ruo8na$742$1@dont-email.me> <86ft2ml6js.fsf@linuxsc.com> <rus4op$d18$1@dont-email.me>

Show all headers | View raw


Andrey Tarasevich <andreytarasevich@hotmail.com> writes:

> On 1/27/2021 7:53 AM, Tim Rentsch wrote:
>
>> Andrey Tarasevich <andreytarasevich@hotmail.com> writes:
>>
>>> On 1/25/2021 11:59 AM, jfbod...@gmail.com wrote:
>>>
>>>> In this case we have to use "struct _Clip *" instead of "ClipPtr"
>>>> to declare the pointers because the "ClipPtr" typedef name doesn't
>>>> exist yet.  You could get around it by forward-declaring the
>>>> struct tag:
>>>>
>>>>       struct _Clip; // forward declaration of the tag name,
>>>>                     //    type is *incomplete* at this point
>>>>
>>>>       typedef struct _Clip *ClipPtr; // you can create typedef names
>>>>                                      //    for incomplete types
>>>>
>>>>       struct _Clip {
>>>>           ClipPtr prev, next;
>>>>           ...
>>>>       };
>>>
>>> To be pedantic, the first declaration (the "forward declaration") is
>>> redundant in this example.  There no need to forward-declare the
>>> type.  You could simply do
>>>
>>>      typedef struct _Clip *ClipPtr;
>>>
>>> and this by itself would be sufficient.  [...]
>>
>> Yes but....
>>
>> This pattern is a dangerous habit to acquire because there are
>> other cases where it does make a difference.  IMO what the rules
>> are here is one of the backwaters of C that is best to avoid, and
>> an easy way to avoid it is to always separate the declaration of
>> a struct type from the typedef that depends on the struct.  If
>> that feels cumbersome then it's easy to write a macro so as not
>> to have to re-write the boilerplate.
>
> Um... No.
>
> Firstly, my remark above is not intended as a stylistic advice to
> "avoid standalone forward declarations altogether since you can
> piggyback them on something else".

No, I didn't think it was.

> My remark above is merely intended
> to demonstrate a fairly curious language feature, which can indeed be
> dangerous to an inexperienced user.  In C a mere mention of `struct T`
> type specifier by itself in virtually any context serves as a forward
> declaration of that type in the given scope.  Some of these contexts
> can be rather surprising, like arguments of `sizeof` or casts.  (Plus
> the peculiar behavior in function declarations and definitions).  This
> is just a bit of language trivia.
>
> Secondly, from the stylistic point of view:  when a forward declaration
> is necessary, I am all for forward-declaring types deliberately and
> explicitly (instead of relying on byproducts of other
> declarations).

Yes, I pretty much took that as a given.

> However, for a user who generally follows the popular
> typedef idiom (i.e. "give each `struct` type a compact typedef alias")
> combining the forward declaration and the `typedef` into a single
> declaration is a perfectly safe and elegant _idiomatic_ way to kill
> both birds with one stone.  This is an example of where brevity is a
> virtue.

My point is that it is NOT _perfectly_ safe, and there are
situations where

    typedef struct clip_struct *ClipPtr;

and

    struct clip_struct;
    typedef struct clip_struct *ClipPtr;

do different things (and when they do, it's more likely that the
second meaning is what was intended).  Granted, such cases don't
occur very often, but that only makes them more insidious when
they /do/ occur.  I daresay most C programmers aren't aware of
this anomaly;  certainly I wasn't before becoming sensitized to
it some years back when reading a discussion in this newsgroup.

> (And the aforementioned typedef idiom is a very good idiom to follow
> specifically because of the aggressively self-declaring behavior of
> full-blown `struct T` type specifiers, even if the compilers are
> supposed to catch most of the accompanying errors.)
>
> Relying on some random "first" declaration to introduce a new `struct`
> type is indeed a dangerous pattern, which is many cases will not do
> what an inexperienced user intended it to do - I'd agree with this
> point.

That isn't what I was suggesting.  Explicit forward declarations
are unequivocally better than "accidental" forward declarations.

> But using the `typedef struct T T` idiom as a unified method of
> forward-declaring a new `struct` type _and_ assigning it a compact
> typedef alias is not only perfectly fine, but is actually highly
> recommended.

The recommendation should come with a caveat that there are
situations where it doesn't do the right thing, and to be
absolutely safe the pattern

    struct whatever_tag;
    typedef struct whatever_tag <typename-declarator>;

should be used instead (or perhaps always, if someone doesn't
want to be bothered with learning what the odd cases are).

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

I need help understand a struct T <T@invalid.invalid> - 2021-01-18 17:01 -0800
  Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 01:37 +0000
    Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-18 17:41 -0800
      Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 01:52 +0000
        Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-18 18:03 -0800
  Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-18 19:00 -0800
  Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 11:34 +0000
    Re: I need help understand a struct Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-19 04:18 -0800
      Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 13:01 +0000
        Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 21:39 +0000
          Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 23:20 +0000
            Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 00:25 +0000
              Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-20 12:42 +0000
                Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 17:39 +0000
                Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-20 19:32 +0000
                Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 20:45 +0000
                Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-21 16:12 +0000
                Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-21 17:10 +0000
                Re: I need help understand a struct Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-21 11:51 -0800
                Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-22 12:26 +0000
                Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-21 20:16 +0000
                Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-21 23:04 +0000
  Re: I need help understand a struct "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2021-01-25 11:59 -0800
    Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-25 21:18 -0800
      Re: I need help understand a struct Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:53 -0800
        Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-27 08:35 -0800
          Re: I need help understand a struct Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 07:48 -0800
            Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-28 09:25 -0800
            Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 18:03 +0000
              Re: I need help understand a struct Guillaume <message@bottle.org> - 2021-01-28 20:46 +0100
                Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 21:31 +0000
                Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-29 11:15 -0800
    Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-25 21:20 -0800

csiph-web