3 ms·
> some of Windows uses 0 to mean success, and some of Windows doesn't. This is unfortunately true of Unixes as well.
by colanderman 2y ago
> some of Windows uses 0 to mean success, and some of Windows doesn't.
This is unfortunately true of Unixes as well.
- jstimpfle 2y agoUnix APIs return -1 on error pretty consistently. The error code can then be read from the errno thread local variable. In the Linux kernel internal APIs (and probably others), -errno is returned directly (no errno mess), which is still negative. The one "Unix" API I know that returns > 0 on error is pthread, which returns +errno directly (but still 0 on success). Which APIs return 0 on error? I can't think of any.
- colanderman 2y ago`malloc(3)`. Many of the functions in string.h.
- jstimpfle 2y agoYeah there are a couple of (3) functions (i.e. not syscall interfaces) that return pointers. It's very common for those to return NULL on error, hardly a surprise. It will also blow up with a segfault should you forget to check success.
- School-Cotton 2y ago> It will also blow up with a segfault should you forget to check success. My guess is this is usually true in practice, but in C and C++ dereferencing a null pointer is UB so you really can't assume that.
- jstimpfle 2y agoYou shouldn't intentionally rely on a segfault as a means of terminating the program -- do sth. like `exit(1)` instead. What I'm saying is there isn't an ergonomic issue with NULL error return APIs. You might prefer algebraic error types (in other languages). I'm not even sure I do. NULL return APIs are clean and simple. If you do (accidentally) forget to check for NULL return code, you will for sure get a segfault on first access in practice (not on embedded platforms maybe). The compiler can't remove any following code unless it can prove only NULL will ever be returned. Don't fall trap to UB FUD.
- School-Cotton 2y ago> The compiler can't remove any following code unless it can prove only NULL will ever be returned. It can reorder code, though. For example, it can change int *x = malloc(sizeof(int)); *x = 42; if (x) launch_the_nukes(); to int *x = malloc(sizeof(int)); launch_the_nukes(); *x = 42;
- jstimpfle 2y agoThe compiler can only reorder when that would be ok in the absence of UB. What can be reordered before the write through the pointer can't read the pointer, and can't really do any damage. Syscalls and library calls (in particular if dynamically linked) can't be reordered before the write because the compiler can't see what the do. Most of the UB FUD are contrived examples that hardly happen in practice. What I'm saying is not that you should write bugs, but that bugs (especially segfaults) will immediately turn up in practice.
- trebligdivad 2y agoI've come across lots of C code which mixes whether it's using -errno, or errno and life all gets messy. And then there's the places where you're returning a pointer not an errno at all. (Which the kernel tries to solve with errptr I think - but there seems to be plenty of places fixing that) And then there's the way that using -errno ends up with ssize_t (signed that is) which also confuses loads of things.