[Toybox] __attribute__((__noreturn__)) vs _Noreturn

Rob Landley rob at landley.net
Thu May 12 10:01:50 PDT 2022


On 5/11/22 11:10, enh wrote:
>> The next version of centos does not exist. Apparently Centos has completely gone
>> away. Right, I can stop caring about it then I guess?
> 
> (that was my reaction to the recent news, yes. "fine by me", since
> centos was _always_ the most problematic distro to support, probably
> because it naturally attracted the kinds of folks who _wanted_ to run
> stuff from a decade ago.)

I can move from 7 years to 10 if there's specific demand for it,  but 7 was
based on a lot of experience and a certain amount of research. It's enough
Moore's Law half lives to get you down to about 2% of the installed base, but
it's ALSO where expertise in the old stuff seems to drop out of living memory.

The old "mirror being 7 years bad luck" was from medieval observations about
people recovering from old traumas, changing behavior, and moving on with their
lives: that's approximately the time it takes a socializing group of humans to
collectively stop reacting to a cause that's no longer present. From a technical
perspective, it means past that point the relevant domain experts are no longer
immediately available. People can dig up and recreate the old ways if you track
down an ex-expert willing to put in some time, but most of them won't have the
answers off the top of their head anymore. They've stopped exercising it,
nobody's regression testing it, have to dig something out out of a box...

Yeah yeah, nebulous social community stuff, but that's important too. Those last
3 years of support in the 10 year time horizon are the most painful for a
REASON. (Somebody could totally do a thesis/dissertation on this if they wanted
to...)

>> If this does actually break somebody, I can have portability.h do:
>> #if version < thingy
>> #define _Noreturn __attribute__((__noreturn__))
>> #endif
>>
>> But I'd rather wait for a complaint?
>>
>> (Also, when I try to build older versions with CFLAGS=--std=c99 to see where c11
>> leaked in, even 0.8.0 won't build because of random failures like
>> CLOCK_MONOTONIC isn't defined? Looks like gcc/glibc is being intentionally
>> obstructive again. I'd rather not micromanage this the same way I refuse to
>> #define gnu to get stuff out of the headers: that way lies madness...)
> 
> interesting, i don't see that for the android build, but maybe we just
> don't build that stuff for the host. (bionic's always [well, "since i
> inherited it"] taken the attitude that you get all the things, all the
> time.

I suspect it would work if I said "gnu99" instead of "c99", but that defeats the
purpose of the exercise. (The gnu guys keep forcing you to #define gnu to get
wrappers for Linux system calls that the kernel guys introduced, like "man 2
unshare". It has nothing whatsoever to do with gnu, never did, but the glibc
guys are political propagandists.)

That said, using the musl toolchain --std=c99 sort of builds-ish, and I can see
that typeof() showed up in commit 5a159cceb in 2017, but to test anything that
old I need commit 78289203031a backported (fixing the config2help segfault in
newer toolchains)...

Yes, the last commit that builds with --std=c99 is commit 77f9c7700604 in May
2017, because commit 5a159cceb introduced use of typeof(), a c11 feature.

That was slightly/technically wrong of me (because 7 year time horizon, only
about 5 and 1/2 years at the time), although the old toolchains I regression
tested against already had typeof() support in their default standards (as an
extension), so it still built on the old versions, even ones that predated the
c11 standard; it was a widely available compiler extension (like a ? : b meaning
a ? a : b) before it was standardized.

Anyway, design.html says c11 now. I should probably have about.html mention it
too, but I'm trying to redo the web page so "about.html" is the default landing
page instead of news.html, and move the intro paragraph at the start of
news.html into header.html so it's on all the pages, but about.html has its own
version and moving it into the header completely screws up the flow of the first
section of the about page requiring a largeish rewrite. :P

> there's very little [though admittedly non-zero] value to being
> able to fine-tune your standard version, but that's _far_ too
> confusing for most developers. "it just works" minimizes our support
> burden, and we have an orthogonal "what version of Android do you want
> this to _run_ on?" problem that's more than enough cognitive load for
> everyone.)

This is why I puppy-eyed Rich into adding _ALL_SOURCE to musl. Just give me all
the darn symbols the C library is providing.

>> > given that `_Noreturn` is required to be at the start, i kind of wish
>> > they'd made it imply `void`; `noreturn void` seems a bit redundant!
>>
>> stdnoreturn.h does literally nothing except #define noreturn _Noreturn
> 
> yeah, but like i said yesterday --- that's how you have your "sensible
> keyword [noreturn]" cake and also eat "don't break existing code
> [no-one's using _Noreturn]".

C99 (and possibly earlier) explicitly reserved _[A-Z] as a future expansion
namespace. (C99 section 7.1.3, "All identifiers that begin with an underscore
and either an uppercase letter or another underscore are always reserved for any
use.") The problem is that means all new things they add in future can only have
_Stupid _Names... And yet typeof() didn't!

  int main(int argc, char *argv) { typeof(argc) x = argc+1; return x; }

Compiles just fine without #including a single header. They added a keyword
outside of any reserved namespace for THIS, but not for noreturn, and this is
why I'm complaining. They are hypocrites.

Toolchain version upgrades break stuff. This is sadly not avoidable. The 7 year
horizon thing gives people time to adapt, but anybody who adds -Werror to their
build scripts voluntarily gives up the right to complain about "apt-get update
du jour broke my build" happening at least annually, let alone major version
upgrades that swap --std defaults...

> if you look at the git history _for
> toybox_ you can see that Apple's *headers* were already using
> `noreturn`, and that's why toybox had to have
> __attribute__((__noreturn__)) rather than __attribute__((noreturn))
> :-)

When there is a standard guaranteeing us a feature, we might as well use the
standardized feature. (I still pick and choose standards, ala LP64 instead of
int_least8_t and int_fast8_t and intmax_t and so on.)

In this project, I tend to want to peel back gratuitous wrappers and understand
what it's actually doing. When I don't care about the underlying implementation,
I use something like Python/Lua/Bash instead of c. :)

Rob



More information about the Toybox mailing list