Comment by zbentley

2 days ago

I'm agreeing with you, to be clear.

But buggy software might not crash; it might compare NULL == NULL and misbehave, instead.

So there's really no good option here, which is why C is a rancid choice of language for publicly-usable APIs. But we're stuck with it. So it goes.

I've been programming in C since 1978 and never until now heard of a function returning "*" on error.

  • This specific manifestation of "C is terrible for shared code APIs" is rare.

    But issues caused by folks forgetting to check errno, miscomparing NULL to NULL when calling multiple APIs, dereferencing external-API-returned NULL due to missed error checking, mishandling inherited errno after successful action, or--the most common--mishandling negative integer return sentinels meant to indicate errors? Those are incredibly common.

    • This specific library call is quite poorly designed.

      Standard C api calls return an integer, which is 0 on success or nonzero on error. Ignoring it is an intentional choice. `errno` is the hack that shouldn't really exist because it's trivially easy to forget to check that and also has issues with threading (patched by making it a thread local) and more recently, coroutines (which admit no general purpose patch because they're a userspace construct).

      Another reason why this is terrible is that it's unclear what the returned pointer's lifetime is. Is it until the next call to crypt? If so, is it thread-local like errno? If it's passed on to the user, is it safe to call free() on it, or is there a crypt_free function that should be called instead?

      But all of this, and I mean all of it pales in comparison to returning '*' on error.

      2 replies →

  • It's not a C thing, it's a Linux thing. The asterisk is relevant to how crypt() is used for /etc/shadow.

               If the password field contains some string that is not a valid result of crypt(3), for instance ! or *, the user will not
               be able to use a unix password to log in (but the user may log in the system by other means).

    • No, it's a C thing. They previously returned NULL for invalid passwd lookups, but because there's no way in C to force API users to decide what to do if an error occurrs, that was causing program crashes due to NULL dereferences.

      So they made the (very bad, but motivated by C's broken design/conventions) decision to return a magic string instead.

      10 replies →

C programs wouldn't accidentally compare NULL to NULL. They'd either check for null explicitly, or they'd pass the null to strcmp and crash.