Live data from Hacker News

Lesser known tricks, quirks and features of C

blog.joren.ga

111–120 of 189 posts

Re: Lesser known tricks, quirks and features of C

#111
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.

At that point you might as well typedef the function pointer type anyway, since it's just another *, and const/volatile variations for functions don't make sense.

Re: Lesser known tricks, quirks and features of C

#112
post #81
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…

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!

It definitely is, but it's that ability to bind it to a specific register that makes all the difference - and, of course, that can't be portable C (although it would be nice if we had non-portable supersets per arch, so that e.g. all x86 compilers would do this the same way).

Re: Lesser known tricks, quirks and features of C

#113
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.

Yes, you can treat "register" as a hint "no pointer to this ever exists anywhere in this program" for the reader. But you can only use it for locals, and that kind of metadata would be most useful (to other devs) on globals and fields - they can already see if a local ever has & applied to it or not.

OTOH I didn't recall this bit, but apparently you can also apply it to arrays. Which keeps them indexable, but you can't take addresses of elements nor of the whole array anymore. Now I'm not sure if the compiler can do anything useful with this, but it would allow it to play with alignment and padding - e.g. storing "register bool x[10]" as 10 words rather than 10 bytes. Is there any architecture on which that would be beneficial, though?

Re: Lesser known tricks, quirks and features of C

#115
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

I love this. Somehow it feels more elegant than "header-only" libraries.

Re: Lesser known tricks, quirks and features of C

#116
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

How does this help? It just moves the content of the .h file to the .c file, but you still need to Write Everything Twice.

Re: Lesser known tricks, quirks and features of C

#117
post #116
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

How does this help? It just moves the content of the .h file to the .c file, but you still need to Write Everything Twice.

It reduces file count in the project browser, renaming/refactoring is much simpler in one file, it just feels like working with a newer language.

Re: Lesser known tricks, quirks and features of C

#118

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…

MSVC supports C11 and C17, minus the C99 stuff that was made optional in C11.

Anyway given the option, one should always favour C++ over C, if they care about secure code, which while not perfect it is much better than any C compiler will do.

Re: Lesser known tricks, quirks and features of C

#119
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

How do you handle third party headers?

I just include them, everything works as before. If I have to create a library then I create a separate header file for the api functions and only the internals are headerless.

Re: Lesser known tricks, quirks and features of C

#120

I wish there was a language "between" assembly and C: basically assembly with some quality-of-life improvements. Shortcuts to reduce redundant chores (like those multiple instructions to load one 64-bit number into an ARM register) but minimal "magic" or unintended consequences as in C. Things like maybe a function call syntax like: CALL someFunc(R1: thingForRegister1, @R7: pushR7ThenPopOnReturn, R42: [memoryAddressF…

I think QBE might be what you're looking for?

https://c9x.me/compile/

Post reply on HN