Live data from Hacker News

Lesser known tricks, quirks and features of C

blog.joren.ga

81–90 of 189 posts

Re: Lesser known tricks, quirks and features of C

#81
post #47
post #7

Most of these are pretty familiar if old enough but this is a wonderful list. I didn’t know C23 was getting rid of trigraphs. That’s probably a good thing and easy to clean up if needed.

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…

It's still useful on non-simple compilers when mixing inline assembly and c, for example `register __m128 foo asm("ymm7")`.

I realize that's a gnu extension - but it's super useful!

Re: Lesser known tricks, quirks and features of C

#82
post #44
post #30

the c training course at a popular uk training company (the instruction set) had duff's device on something like page 5 of their c course - expunging it was one of the first things i did when i joined them. there were many others.

i don't ask this too often - but what is wrong with this comment?

I presume you angered the Duff Defenders (there are those that feel C shouldn’t be taught unless you’re taught all the weird things it can do).

Re: Lesser known tricks, quirks and features of C

#83

Compound Literals in C are great. They're no surprise to anyone coming from more sophisticated languages, but I've never seen them used in the C codebases I've worked on. What with C also allowing structures as return values, another rarely-used feature, they're really useful for allowing a richer API than the historical `int foo(...)` that so many people are used to seeing. C has so much legacy that it's really hard…

[deleted]

Re: Lesser known tricks, quirks and features of C

#84
post #82
post #44

Earlier quoted context omitted.

i don't ask this too often - but what is wrong with this comment?

I presume you angered the Duff Defenders (there are those that feel C shouldn’t be taught unless you’re taught all the weird things it can do).

yes, that was probably my feeling at the time. but perhaps a bit much for people struggling with compiling and running hello world.

Re: Lesser known tricks, quirks and features of C

#85
post #64

Earlier quoted context omitted.

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.

Oh yes! I totally agree with that approach; I find it much clearer to typedef the function type rather than the function pointer type:

    typedef int (*CallbackPtr)(int,int);
    void foo(..., CallbackPtr callback);
always reads less clearly to me than

    typedef int Callback(int,int);
    void foo(..., Callback* callback);
I find this especially useful in C++ where the callback type could conceivably be some other type like std::function. Seeing that * helps me know at a glance it's probably just a plain old function pointer.

Though I think maybe clearest of all is to not use a typedef, provided it doesn't cause other readability problems:

    void foo(..., int (*callback)(int,int));
(Not meaning to steal your thunder here... just wanted to write out an example in case anyone else was curious.)

Re: Lesser known tricks, quirks and features of C

#86
post #75

Earlier quoted context omitted.

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.

At least for GCC/clang, you can mark your functions with special __attribute__ format.

For loading translated strings, I'm missing some library function to verify whether two format strings are argument-compatible.

Re: Lesser known tricks, quirks and features of C

#87
post #72

Earlier quoted context omitted.

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.

Depends on the compiler, but you'd mark the printf function with something like: __attribute__((format(printf, 1, 2)))

Re: Lesser known tricks, quirks and features of C

#88

It’s cool to have these, it’s fun to use them for fun. But please don’t use them in production code. Also don’t assume most of them will he known by other developers.

Please don’t use C at all in production if you can help it.

So no Unix, Linux, Bash, cURL, Ruby, ...?

Re: Lesser known tricks, quirks and features of C

#89

It’s cool to have these, it’s fun to use them for fun. But please don’t use them in production code. Also don’t assume most of them will he known by other developers.

Please don’t use C at all in production if you can help it.

The entire world runs on C. Even if you’re not writing new C code, it is useful to understand.

Re: Lesser known tricks, quirks and features of C

#90
post #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 ...

When I wrote a lot of cross platform performant numerics I loved the bus error thrown by the Sun machines.

In essence it was a RISC machine saying "I can't deal with unaligned data" and a sign that code was (say) storing a 32 or 64 bit int that straddled a word boundary and the hardware was not coping on a MOV.

Why did that matter and why was it good thing?

It forced programmers to think about data alignment and resulted in code that run faster on CISC Intel chips.

The dirty secret about Intel chips was they "just did it" w/out complaint - and it slowed them down significantly on pipelined computations if they were constantly double handling unaligned data to get it from memory (across a word boundary) to bus (aligned for transit) to memry again (across a word boundary).

Post reply on HN