This is intended for environments without implementations for abort(), fprintf(), and stderr. e.g., embedded systems. Those can provide their own implementations of default_illegal_callback_fn and default_error_callback_fn at compile time.
If you want to use your own default callback, things will be somewhat inconsistent unfortunately: We cannot make the callback data extern too, because then the initialization lists for default_illegal_callback won’t contain only constants. (const variables are not compile-time constants). So you cannot take callback data in your own default callback function.
As a more drastic/breaking alternative I suggest to remove the callback data entirely. I don’t think it’s a big loss and I would be surprised if anyone uses it. Additionally, we could even remove the possibility to set the callback function at runtime after this PR. This will simplify things a lot, and again I don’t think it’s a big loss.
Note that abort(), fprintf(), and stderr are also used in CHECK, which is still used in production code if we rely on gmp for scalar and field inversions (e.g., https://github.com/bitcoin-core/secp256k1/blob/master/src/scalar_impl.h#L240). This is not an issue for embedded system which probably don’t want to use gmp anyway, but it is probably an issue for the reasons explained in #566 (comment).
(related downstream: https://github.com/rust-bitcoin/rust-secp256k1/pull/100 @elichai)