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.