Live data from Hacker News

My review of the C standard library in practice

nullprogram.com

11–20 of 94 posts

Re: My review of the C standard library in practice

#11
post #7

>Without libc you don’t have to use this global, hopefully thread-local, pseudo->variable. Good riddance. Return your errors, and use a struct if necessary. On contrary you should absolutely use errno, if only to report your IO errors. Or maybe he never does IO. After all a program that doesn't output anything is likely safer, since these are all evil side effects. I can just see that new programming paradigm: "side…

If you don't understand why errno is bad then it'll be hard to explain it.

Errno is fine if you're accessing it right after a stdlib function that sets it, because it's the equivalent of a function's error code. Once you get out of that context errno becomes less and less useful and probably shouldn't be used, because without that context you won't know who/what actually set it.

Re: My review of the C standard library in practice

#12
post #11
post #7

>Without libc you don’t have to use this global, hopefully thread-local, pseudo->variable. Good riddance. Return your errors, and use a struct if necessary. On contrary you should absolutely use errno, if only to report your IO errors. Or maybe he never does IO. After all a program that doesn't output anything is likely safer, since these are all evil side effects. I can just see that new programming paradigm: "side…

If you don't understand why errno is bad then it'll be hard to explain it. Errno is fine if you're accessing it right after a stdlib function that sets it, because it's the equivalent of a function's error code. Once you get out of that context errno becomes less and less useful and probably shouldn't be used, because without that context you won't know who/what actually set it.

That’s all documented in the standard though. Why would you access errno any other way?

Re: My review of the C standard library in practice

#13

Earlier quoted context omitted.

So one should focus on creating versioned API IMO. Nobody does that for some reason. I should be able to declare my program to use v2023 API and consume libraries which use v1975 API.

That doesn't work in languages with nominal types, and even structurally-typed languages can have a hard time. You call a function that returns a v1975/SomeStruct and pass it to a function expecting a v2022/SomeStruct. What does the new function do when some of the struct fields are set to invalid values?

What if the type was a "Some1975Struct" that got passed? Then that would give a huge blaring error because it's not the same type as a "Some2022Struct".

Re: My review of the C standard library in practice

#14

Earlier quoted context omitted.

That doesn't work in languages with nominal types, and even structurally-typed languages can have a hard time. You call a function that returns a v1975/SomeStruct and pass it to a function expecting a v2022/SomeStruct. What does the new function do when some of the struct fields are set to invalid values?

What if the type was a "Some1975Struct" that got passed? Then that would give a huge blaring error because it's not the same type as a "Some2022Struct".

The naming convention isn't important. If the structs are from different versions of the library then you either have a type error (nominal types) or have to figure out the semantics of arbitrarily uninitialized fields.

Re: My review of the C standard library in practice

#15
post #10
post #7

>Without libc you don’t have to use this global, hopefully thread-local, pseudo->variable. Good riddance. Return your errors, and use a struct if necessary. On contrary you should absolutely use errno, if only to report your IO errors. Or maybe he never does IO. After all a program that doesn't output anything is likely safer, since these are all evil side effects. I can just see that new programming paradigm: "side…

Lots of APIs allow reporting of I/O errors without use of an errno-like construct.

> Lots of APIs allow reporting of I/O errors without use of an errno-like construct.

libc included--the C11 threads API returns some errors directly using the constants thrd_busy, thrd_nomem, and thrd_timedout. Unfortunately, it also uses a catch-all constant, thrd_error, for other errors.

The pthreads API returns errno values directly as return values, but that's POSIX, not C.

Re: My review of the C standard library in practice

#16
post #11
post #7

>Without libc you don’t have to use this global, hopefully thread-local, pseudo->variable. Good riddance. Return your errors, and use a struct if necessary. On contrary you should absolutely use errno, if only to report your IO errors. Or maybe he never does IO. After all a program that doesn't output anything is likely safer, since these are all evil side effects. I can just see that new programming paradigm: "side…

If you don't understand why errno is bad then it'll be hard to explain it. Errno is fine if you're accessing it right after a stdlib function that sets it, because it's the equivalent of a function's error code. Once you get out of that context errno becomes less and less useful and probably shouldn't be used, because without that context you won't know who/what actually set it.

Assuming there is no thread context switch or OS signals between those calls.

Re: My review of the C standard library in practice

#17
post #16
post #11

Earlier quoted context omitted.

If you don't understand why errno is bad then it'll be hard to explain it. Errno is fine if you're accessing it right after a stdlib function that sets it, because it's the equivalent of a function's error code. Once you get out of that context errno becomes less and less useful and probably shouldn't be used, because without that context you won't know who/what actually set it.

Assuming there is no thread context switch or OS signals between those calls.

errno is thread-local, so you don’t have to worry about context switches.

Re: My review of the C standard library in practice

#18
post #17
post #16

Earlier quoted context omitted.

Assuming there is no thread context switch or OS signals between those calls.

errno is thread-local, so you don’t have to worry about context switches.

You won't find that on either ISO C nor POSIX specifications.

It only happens to be implemented that way in some environments, as a macro to either thread local or some function call that retrieves the right errno.

Still, even that doesn't take care about signal handling.

Re: My review of the C standard library in practice

#19

This just goes to show how hard it is to create a API to last 30 years. So much has changed since then, but libc needs to keep the same API. Things like Unicode and the internet (which brought the need for security to forefront) have come into popularity since then, but you can’t fix the old functions.

So one should focus on creating versioned API IMO. Nobody does that for some reason. I should be able to declare my program to use v2023 API and consume libraries which use v1975 API.

No, one should focus on creating smaller independent modules and don't mix unrelated stuff like networking fundamentals with string convenience functions.

Re: My review of the C standard library in practice

#20
post #18
post #17

Earlier quoted context omitted.

errno is thread-local, so you don’t have to worry about context switches.

You won't find that on either ISO C nor POSIX specifications. It only happens to be implemented that way in some environments, as a macro to either thread local or some function call that retrieves the right errno. Still, even that doesn't take care about signal handling.

Excerpt from C11:

"[...] errno which expands to a modifiable lvalue that has type int and thread local storage duration"

Post reply on HN