As someone who targets clang/gcc/msvc/icc, I don't see much value in these defines. Let's pick on HAVE_STRDUP: what's the point?
If it's always defined on your target platforms, just use the stdlib unconditionally - the define is pointless.
If it's never defined on your target platforms, you'll have to roll an alternative of your own no matter what - the define is pointless.
So the presumed theoretical use case for this is if you sometimes want to define your own, and sometimes want to use the standard library. But do I actually want that? Rarely. Very rarely. If I care to target old systems, I'd generally rather unconditionally define my own version that doesn't conflict with the standard library, that gets tested and used in all builds on all platforms - it'll be less code than adding a bunch of #ifdef soup, and it'll be less brittle - no "works on my machine but fails on the build server" nonsense because of a typo in sometimes-dead code.
That leaves one even narrower use case which isn't entirely theoretical: wanting to backport a modern codebase to an "ancient" toolchain/stdlib via polyfills without touching the modern codebase or the toolchain/stdlib. That approach has it's niches, but... it is worth emphasizing, niches.
There are some few cases where I'd probably prefer the "standard" version where available: memcpy etc. that are often extensively optimised, and that are a lot of work to write a non-naive version off that performs well. But I agree that most of the time you categorically should not use feature detection like that, and in the few cases you're dealing with systems lacking things that basic you have bigger problems...
I was curious where this was from, so I looked at https://gitlab.com/esr/autodafe/-/blob/master/de-autoconfisc...
As someone who targets clang/gcc/msvc/icc, I don't see much value in these defines. Let's pick on HAVE_STRDUP: what's the point?
If it's always defined on your target platforms, just use the stdlib unconditionally - the define is pointless.
If it's never defined on your target platforms, you'll have to roll an alternative of your own no matter what - the define is pointless.
So the presumed theoretical use case for this is if you sometimes want to define your own, and sometimes want to use the standard library. But do I actually want that? Rarely. Very rarely. If I care to target old systems, I'd generally rather unconditionally define my own version that doesn't conflict with the standard library, that gets tested and used in all builds on all platforms - it'll be less code than adding a bunch of #ifdef soup, and it'll be less brittle - no "works on my machine but fails on the build server" nonsense because of a typo in sometimes-dead code.
That leaves one even narrower use case which isn't entirely theoretical: wanting to backport a modern codebase to an "ancient" toolchain/stdlib via polyfills without touching the modern codebase or the toolchain/stdlib. That approach has it's niches, but... it is worth emphasizing, niches.