8 ms·
I really enjoyed "Deep C Secrets" as an intermediate C book: Expert C Programming: Deep C Secrets https://www.amazon.com/dp/0131774298/ https://www.amazon.com/
by bello 9y ago
I really enjoyed "Deep C Secrets" as an intermediate C book:
Expert C Programming: Deep C Secrets https://www.amazon.com/dp/0131774298/ https://www.amazon.com/dp/0131774298/
A little dated, still lots of relevant knowledge though.
- sifoo 9y agoOne of my all time C favorites.
- geokon 9y agoWhat I liked about this book is that it's very upfront about how messed up C is. I read about half of it and it made me never want to write any C ever again. An especially memorable part for me was how it took 3 pages of language lawyering to explain why this doesn't compile: foo(const char **p) { } main(int argc, char **argv) { foo(argv); }
- int_19h 9y agoI don't see this as a good example of "how messed up C is". It doesn't compile because you're violating const correctness, and any other language with similarly sound correctness requirements would flag it in a similar way. If anything, this is one of those rare cases where C chooses correctness over convenience. It takes quite a bit to explain because the "common sense" is that if one level of pointer indirection allows you to pass non-const where const is expected, then two levels shouldn't be any different. But common sense is wrong, and the compiler is right. And it doesn't require any language lawyering, either - all you need to do is slightly tweak the example to show why exactly it is unsafe.
- rcxdude 9y agoA better example of messed up in that example is how it's not a compile-time error (but is very nasty undefined behavior) for the function without an explicit return type (so defaulting to int) to end without returning anything.
- int_19h 9y agoCompilers can - and, indeed, do - diagnose UB as compile time errors, or at least warnings (which you can then turn into errors if you want) all the time. Now, it is not undefined behavior for the function to not return anything despite having a return type. It is UB for the caller to try to use the returned value, but in this case it's not actually used. The implicit int feature is really very much deprecated (in fact, it was already removed in C99, almost 20 years ago!). If, for some mysterious reason, you're trying to compile code like that, it's probably very old code dating to before C was an ANSI standard, and void return type was a thing. In such code, it would be pretty common for functions to not return anything, because semantically they don't - it was just a quirk of the language that there was no notion to express a non-value-returning function back then, and so returning an (undefined) int became idiomatic. In C89, this entire behavior was retained largely because backwards compatibility was necessary. C99 finally fixed it.