Path: csiph.com!weretis.net!feeder8.news.weretis.net!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: I need help understand a struct
Date: Wed, 27 Jan 2021 07:53:59 -0800
Organization: A noiseless patient Spider
Lines: 37
Message-ID: <86ft2ml6js.fsf@linuxsc.com>
References: <478ca6d1-babd-47b4-b9f5-09fba105d9f6n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="a3a7a3546220eb2a4a7cfe4d4683198c"; logging-data="13758"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18+A2tQ7ebcwoHJ+jcz6H8fsCEGfuk6lIQ="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:3V0AykOM+HOANHV6/5KVLocEERY= sha1:0tdEJvZmcXg3F8aC6KMSe5gsyOw=
Xref: csiph.com comp.lang.c:158650
Andrey Tarasevich 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.