It may be an idea to have a step between 2 and 3 with NO default, to force everyone who compiles their code against your header files to make their choice explicit.
That would be untenable - I wouldn't be able to cleanly `gcc -o blah blah.c` without making an explicit decision, and by extension wouldn't be able to (continue to) compile existing code either.
Rebuilds on every codebase everywhere ever would promptly blow up.
IMHO the revolts would come from two camps, a) bureaucracies for whom a build system change would normally take months, and b) individual devs who would be all like "compilation flags?? in MY defaults?! that's LESS likely than you think!".
Worst case scenario, someone forks glibc, removes the offending requirement, proffers commercial support for their fork... and ends up making bank.
painful yes, but isn't that a win? If it's breaking at build time, that means someone's actually /building/ their app. And the fix is easy enough (as long a they don't set it to 32 bit...).
The bigger issue is all the systems that won't be rebuilt (per several sibling comments).
There is no "no default", your distro will ship with one or the other. Very few people compile and ship glibc, upstream defaults only matter in the way they affect distro defaults.
The macros aren't set when building the libc, they are set when programs using the libc are build. So every program build on a distribution uses either the default or set one of the macros.
> [H]ow does glibc maintain ABI compatibility? Alias attributes?
Symbol versioning[1,2]. Kind of like aliases, but more awkward. In theory it’s not specific to glibc, in practice hardly anyone else bothers being so careful about their ABI.
Note that dynamically linked musl, which Alpine uses (I think..?), doesn’t understand symbol versioning, though I expect this will only last until the first ABI break in musl.
I know that glibc uses symbol versioning to remain ABI-compatible within versions. What I meant was ABI compatibility between 32-bit and 64-bit time_t with the same glibc library. Looks like it uses something like aliases for that (but self-implemented using asm):
musl has lasted almost one-third as long as glibc, with significantly less than one-third the number of ABI breaks. as far as I know, the only musl ABI break has been time64; despite glibc's supposedly superior version handling, musl has completed time64 support with headers only, whereas glibc is still in progress.
I think that would be a bad idea in this specific case.
Why? Because for the majority of codebases, the time_t change won't require any work.
You'd be forcing a compiler error, and it would effectively say "Add -D_TIME_BITS=64. If you're doing something really weird with time_t then you may have to update your code too, but in 95% of the cases, you can just add that flag."
I think the compiler error might be warranted for something like "You are using a function that is 95% of the time insecure or wrong, please add -DGAPING_SECURITY_HOLE if you know what you're doing", but if the error really is just "add a flag, you do not need to think about your code probably", the library authors themselves might as well default it for you.