Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Struct Error Date: Thu, 30 Jan 2025 11:51:56 -0800 Organization: A noiseless patient Spider Lines: 100 Message-ID: <86zfj8yt9f.fsf@linuxsc.com> References: <20250124163740.00006281@yahoo.com> <86jzad28d5.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Thu, 30 Jan 2025 20:51:57 +0100 (CET) Injection-Info: dont-email.me; posting-host="8398b997425c6ac61eec19d85d38cad2"; logging-data="3256961"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/YnMpxiRnkoCmgpNPMZkush3PHDf7P/Xk=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:wSKXbQBf6ZqTEC3RXFQDC3MPbsU= sha1:AyMCm95HTuZicrBzhFJ2Yb8xLlA= Bytes: 4652 bart writes: > On 29/01/2025 10:59, Tim Rentsch wrote: > >> bart writes: >> >>> On 24/01/2025 14:37, Michael S wrote: >>> >>>> On Thu, 23 Jan 2025 10:54:10 +0000 >>>> bart wrote: >>>> >>>>> On 23/01/2025 01:05, James Kuyper wrote: >>>>> >>>>>> On 2025-01-22, bart wrote: >>>>>> >>>>>>> Gcc 14.1 gives me an error compiling this code: >>>>>>> >>>>>>> struct vector; >>>>>>> struct scenet; >>>>>>> >>>>>>> struct vector { >>>>>>> double x; >>>>>>> double y; >>>>>>> double z; >>>>>>> }; >>>>>>> >>>>>>> struct scenet { >>>>>>> struct vector center; >>>>>>> double radius; >>>>>>> struct scenet (*child)[]; >>>>>>> }; >>>>>> >>>>>> 6.7.6.2p2: "The element type shall not be an incomplete or >>>>>> function type." >>>>>> >>>>>> I have many draft versions of the C standard. n2912.pdf, dated >>>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the >>>>>> type is incomplete144) until immediately after the closing brace >>>>>> of the list defining the content, and complete thereafter." >>>>>> >>>>>> Therefore, struct scenet is not a complete type until the closing >>>>>> brace of it's declaration. >>>>> >>>>> Wouldn't this also be the case here: >>>>> >>>>> struct scenet *child; >>>>> }; >>>> >>>> Just to point out if it was not said already: the problem is not >>>> related specifically to recursive structures. It applies to arrays >>>> of incomplete types in all circumstances. >>>> >>>> struct bar; >>>> struct bar (*bag)[]; // error >>>> typedef struct bar (*bat)[]; // error >>> >>> I don't think anyone has yet explained why that is an error (other >>> than C says it is), but not this: >>> >>> struct bar *ptr; >>> >>> This is a pointer to an incomplete type. Attempts to do ++ptr >>> for example will fail later on if that struct has not yet been >>> defined. >>> >>> So why not the same for the pointer-to-array versions? >> >> The question you should be asking is why did the original C >> standards body make the rule they did? >> >> The answer might be because this exception to a simple and >> general rule is almost never useful, and never necessary. > > Well, you never see such a thing in use, certainly. I wonder why > that is! > > When a language outlaws some particular construction, forcing > people to stick to a particular idiom (the common use of a T* type > to work with pointers and arrays instead of the more sensible and > safer T(*)[]), then clearly you're not going to see such uses in > the field. > > Although there are really two parts to it: use of T(*)[] > generally (outside of self-referential structs) is allowed, but > that is still rare, presumably because the syntax is too unwieldy. > Or people simply don't know about it, since everyone uses T*. I didn't say this use case isn't used. I said this use case is almost never useful. >> Considering that it has been 35 years since that original rule >> was made, and 2025 is the first time the question has come up, >> the indications are that the original decision was a good one. > > We don't know that. Perhaps it comes up all the time, people > realise they can't use such a construct, and use a different > approach. We don't know that there has never been a person 50 feet tall either, but that doesn't mean there has been one.