|
Message-ID: <20220419162647.GA10881@brightrain.aerifal.cx> Date: Tue, 19 Apr 2022 12:26:49 -0400 From: Rich Felker <dalias@...c.org> To: libc-coord@...ts.openwall.com Subject: Macro-based advertisement of libc extensions, cont'd Context is picking back up the proposal from 2020: https://www.openwall.com/lists/libc-coord/2020/04/22/1 Message-ID: <20200422173825.GA8375@...ghtrain.aerifal.cx> On the basis of a user frustrated at not having a configure-probe-free way to look for extensions (for header-only library use), I started looking at this again, actually digging into the scope of what needs to be covered. I have a partial list of the interfaces from musl I would want to advertise the presence of (which I'll post in a follow-up when I flesh it out a bit more), and some general thoughts from sorting through them: 1. A number of the nonstandard interfaces we have are purely legacy things that serve no purpose in new code -- for example, setbuffer and setlinebuf in stdio.h, which have direct portable rephrasing in terms of the standard C setvbuf. I'm of the opinion that these should be omitted entirely, and that, in general, decisions to advertise the presence of an extension via a macro should be motivated by that extension having some utility in facilitating portability. 2. Extensions fall into at least 2 broad groups by how they're exposed: many are additional declarations in standard headers, while others have their own nonstandard headers. For the former, it's plausible that existing implementations differ as to where they're declared (and this may vary by FTMs). This probably helps decide whether to expose the macros via the same header exposing the interfaces, or via unistd.h. 3. I think the list I'm making from musl is actually a really good cross-platform starting point for this, specifically because in musl we've been careful about only including extensions that other existing implementations are widely in agreement on. That's not to say there aren't a fairly large number of other extensions that should be exposable via this proposal that musl doesn't have, but that the ones from my list should be pretty much entirely non-controversial and a good starting point for populating the "spec". 4. None of my investigation yet includes advertising of behavioral properties that can't be compile-tested. I'll look more into that as a separate phase. A good first case to look at advertising would be extension format specifiers accepted by printf and strftime. So, some specifics for this proposal: For individual interfaces, macro is exposed where the interface is exposed, under the same conditions (FTMs) that expose it. For example: string.h: void *memmem(const void *, size_t, const void *, size_t); #define _EXT_MEMMEM 202204L The value of the macro works like POSIX ones, where the date-style version should reflect when the macro was added to the official list, and specifically, can be less than the earliest version in the official list if it's being advertised tentatively before inclusion. I would expect applications to just do #if _EXT_MEMMEM > 0 or #if defined(_EXT_MEMMEM) && _EXT_MEMMEM > 0 or whatever warning-avoiding tricks they like, but the version allows handling of any mistakes (advertising something that turns out not to actually have cross-platform commonality) if that's ever needed. The special value of 0 also exists, as proposed before, for functionality that's available for link but might not be available at runtime. For extension headers, unistd.h declares the availability of the header. For example: unistd.h: #define _EXT_SYS_AUXV_H 202204L sys/auxv.h: unsigned long getauxval(unsigned long); #define _EXT_GETAUXVAL 202204L Strictly speaking, advertising individual baseline functions for the extension header like this is not necessary; presence of the header could be deemed to imply them. However it seems to be polite in case there's any doubt about whether future implementations might have a same-named extension header without the same idea of what constitutes "baseline" functionality for it. Not that advertising headers like this overlaps in functionality with __has_include in recent compilers. I still think it's useful in that it doesn't assume compiler features and relies on what the implementation reports rather than on probing files -- the whole point of this proposal is allowing the implementation to self-describe extensions in ways that don't require probing. In some cases, implementations might differ in where they expose an interface. A program trying to use getentropy portably might do: #define _BSD_SOURCE #define _GNU_SOURCE #include <unistd.h> #if _EXT_SYS_RANDOM_H #include <sys/random.h> #endif #if #_EXT_GETENTROPY > 0 // ... #endif
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.