Live data from Hacker News

Lesser known tricks, quirks and features of C

blog.joren.ga

71–80 of 189 posts

Re: Lesser known tricks, quirks and features of C

#71

> volatile type qualifier > This qualifier tells the compiler that a variable may be accessed by other means than the current code (e.g. by code run in another thread or it's MMIO device), thus to not optimize away reads and writes to this resource. It's dangerous to mention cross-thread data access as a use case for volatile. In standard C, modifying any non-atomic value on one thread, while accessing it on another…

`volatile` is one of the things we need to pay attention to when dealing with threads, but as you notice it's not the only one.

Eskil Steenberg talks about it at 12:42 in his talk Advanced C: The UB and optimizations that trick good programmers. [0]

[0]: https://youtu.be/w3_e9vZj7D8?t=762

Re: Lesser known tricks, quirks and features of C

#72
post #35

Earlier quoted context omitted.

"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!

Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.

How could that really work? printf is a library function, not an intrinsic. A function named printf can do anything your heart desires.

Re: Lesser known tricks, quirks and features of C

#73
post #64
post #50

One non-obvious thing about named function types is that they can also be used to declare (but not define) functions: typedef void func(int); func f; void f(int) {} I don't think I've ever seen a practical use for this in C, though. In C++, where this also works, and extends to member functions, this can be very occasionally useful in conjunction with decltype to assert that a function has signature identical to some…

I have found this pretty handy for declaring a bunch of functions of all the same type, e.g. steps in a direct-threaded interpreter. typedef void Step(whatever...); Step add,sub,mul,div, load,store, etc...;

I've seen this used to define function pointers / callbacks in a "cleaner" way. I think Mg does this IIRC.

Re: Lesser known tricks, quirks and features of C

#74
post #47

Earlier quoted context omitted.

The bit about "register" is old enough that I don't think it's meaningful anymore. The stock verbiage about how modern compilers ignore "register" because they can do better but it may be useful on simpler ones, has been around in this exact form 20 years ago already. And one curious thing is that even back then, such statements would never list specific compilers where "register" still did something useful. So far a…

I think register is closer to const, as in: it's a hint to the programmer not the compiler. So if you want to make absolutely sure that a variable can always be in a register then you should consider adding the register specifier to stop other programmers from taking the address of that variable.

Taking the address of a variable does not prevent the compiler from putting it in a register. Indeed, it can be convenient to have small utility functions which are always inlined, which take pointers to their results; this should not and does not prevent those results from staying in registers.

Re: Lesser known tricks, quirks and features of C

#75
post #35

Earlier quoted context omitted.

"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!

Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.

One reason is locale-dependent format strings which are loaded from resource files.

Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.

Re: Lesser known tricks, quirks and features of C

#76
post #49

Do we have something like this for C++ (parts not shared with C)?

Can't say for all, but I am reasonably certain C++ does not support designated initializers/sparse array definitions. Some of these features where added in more recent revisions to the C specification from which C++ has diverged from. I would expect most of the differences would become more pronounced starting with C99.

Re: Lesser known tricks, quirks and features of C

#77
post #18

Earlier quoted context omitted.

C is fundamentally confused, because it offers (near) machine-level specifications but then leaves just enough wiggle room for compilers to "optimize" (through alignment and such) while ruining the precision of a specification. You end up not getting exactly what you want at the machine level. It's infuriating. The bitfield stuff in C would be fantastic if it weren't fundamentally broken. E.g. some Microsoft compiler…

I think the problem with this is the C compiler has to find a solution which work with all the architectures it is expected to support. It order to achieve this, it must generalize in some areas and have flexibility in others. C programmers are required to be familiar with both the specifics of the architectures they are building for and the idiosyncrasies of their complier. I always assumed most other compiled langu…

> Bitfields in C can be manageable.

For the use case of specifying a more efficient representation of a fiction confined to the program, then no harm, no foul. But the use case of specifying a hardware- or network- or ABI-specified data layout, then you need those bits in exactly the right spot, and the compiler should have no freedom whatsoever. (I'm thinking of the case of network protocol packets and hardware memory-mapped registers).

Re: Lesser known tricks, quirks and features of C

#78
post #62

I'm a bit better at English than c, and in the spirit of language peculiarities, this jumped out at me: > It's possible, because C cares less than more about whitespace Idiomatically we'd say 'couldn't care less'. I guess we should be glad it wasn't the diabolical and illogical 'could care less'

I don't believe those are functionally / semantically equivalent - couldn't care less does imply a min() value of care. In contrast, the author is suggesting a comparative only. And, on careful re-reading, I suspect the author is having a play on syntax & semantics here -- the context of the quote is: > You may ask, since when C has such operator and the answer is: since never. --> is not an operator, but two separat…

Hah, unfortunately this bit of "poetry" wasn't intentional. I just meant that C does care about whitespace, just not a lot.

Re: Lesser known tricks, quirks and features of C

#79

"Expert C Programming: Deep C Secrets" is a really good book to learn a lot of C tricks and quirks, plus some history. I read it a few years ago and loved it. I was a grad when I read it and remember annoying my older coworkers for a few weeks with little gotchas I picked up. "hey what do you think THIS example prints?" "Stop sending me these!"

[deleted]

Re: Lesser known tricks, quirks and features of C

#80

"Expert C Programming: Deep C Secrets" is a really good book to learn a lot of C tricks and quirks, plus some history. I read it a few years ago and loved it. I was a grad when I read it and remember annoying my older coworkers for a few weeks with little gotchas I picked up. "hey what do you think THIS example prints?" "Stop sending me these!"

Fabulous book, includes a section "Bus Error, Take the Train" explaining the "bus errors" one found on Sun hardware ...
Post reply on HN