From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 7926 invoked from network); 6 Oct 2021 15:44:05 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 6 Oct 2021 15:44:05 -0000 Received: (qmail 7417 invoked by uid 550); 6 Oct 2021 15:44:02 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 7399 invoked from network); 6 Oct 2021 15:44:02 -0000 Date: Wed, 6 Oct 2021 11:43:49 -0400 From: Rich Felker To: Pascal Cuoq Cc: "musl@lists.openwall.com" Message-ID: <20211006154349.GA7074@brightrain.aerifal.cx> References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] STRUCT _IO_FILE { char __x; }; as the poor C programmer's abstract struct On Wed, Oct 06, 2021 at 01:49:16PM +0000, Pascal Cuoq wrote: > Hello, > > The file stdio.h contains: > > #if __STDC_VERSION__ < 201112L > #define __NEED_struct__IO_FILE > #endif > … > #include > > And the file alltypes.h is generated from alltypes.h.in which contains: > > STRUCT _IO_FILE { char __x; }; > TYPEDEF struct _IO_FILE FILE; > > This means that when the compiler defines __STDC_VERSION__ to less > than 201112L, a bogus definition for the type FILE and for the > prototypes of functions that access values of this type can exist in > files outside musl, alongside the real definition from stdio_impl.h > which exists in files inside musl: > > struct _IO_FILE { > unsigned flags; > unsigned char *rpos, *rend; > int (*close)(FILE *); > … > > This is at least a minor annoyance when trying to do source-level > verifications on a mix of source files including some files that > implement musl together with some files that use musl from the > outside. > > Was it only in C11 that it became possible to avoid this ugly hack? > > (We stumbled on this because we happened to be doing the > pre-processing with -std=c99, and I think it should be no problem to > change it to be done with -std=c11, but I'm surprised nevertheless > because I don't see which item in > https://port70.net/~nsz/c/c11/n1570.html#Forewordp6 corresponds to > this change between C99 and C11. Could the test be changed to > “__STDC_VERSION__ < 199901L”?) The change was indeed between C99 and C11, and was obfuscated by a change to the definition of "object type" in 6.2.5, from: Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes). to: Types are partitioned into object types (types that describe objects) and function types (types that describe functions). At various points within a translation unit an object type may be incomplete (lacking sufficient information to determine the size of objects of that type) or complete (having sufficient information). This changed the meaning of the 7.21.1 ¶2 requirement that FILE be an object type. Despite this seeming like an inadvertent change, I'm pretty sure (based on anecdotes and possibly the Rationale document?) that this was just the usual twisted mechanations of WG14 and that the effect was intentional. Note that for musl internal source files, you really should be preprocessing them with src/include/* (introduced in commit 13d1afa46f8098df290008c681816c9eb89ffbdb) exposed. This will take care of suppressing the 'fake' definition of struct _IO_FILE. Rich