Here's a list of mildly interesting things about the C language that I learned over time.
- Combined type and variable/field declaration, inside a struct scope: https://godbolt.org/g/Rh94Go
- Compound literals are lvalues: https://godbolt.org/g/Zup5ZB
- Switch cases anywhere: https://godbolt.org/g/fSeL18 (also see: Duff's Device)
- Flexible array members: https://godbolt.org/g/HCjfzX
- {0} as a universal initializer: https://godbolt.org/g/MPKkXv
- Function typedefs: https://godbolt.org/g/5ctrLv
- Array pointers: https://godbolt.org/g/N85dvv
- Modifiers to array sizes in parameter definitions: https://godbolt.org/z/SKS38s
- Flat initializer lists: https://godbolt.org/g/RmwnoG
- What’s an lvalue, anyway: https://godbolt.org/g/5echfM
- Void globals: https://godbolt.org/z/C52Wn2
- Alignment implications of bitfields: https://godbolt.org/z/KmB4CB
Special mentions:
- The power of UB: https://godbolt.org/g/H6mBFT. This happens because:
- LLVM sees that
side_effects
has only two possible values: NULL (the initial value) orthis_is_not_directly_called_by_main
(ifbar
is called) - LLVM sees that
side_effects
is called, and it is UB to call a null pointer - UB is impossible, so LLVM assumes that
bar
will have executed by the timemain
runs rather than face the consequences - Under this assumption,
side_effects
is alwaysthis_is_not_directly_called_by_main
.
- LLVM sees that
- A macro that tells you if an expression is an integer constant, if you can't use
__builtin_constant_p
: https://godbolt.org/g/a41gmx (from Martin Uecker, on the Linux kernel ML) - You can make some pretty weird stuff in C, but for a real disaster, you need C++. Labels inside expression statements in really weird places: https://godbolt.org/g/k9wDRf.
(I have a bunch of mildly interesting in C++ too, but so does literally everyone who’s used the language for more than an hour, so it’s not as interesting.)