Whenever the subject of C/C++ quirks is brought up, I always like to point out the Deep C/C++ presentation: http://www.pvv.org/~oma/DeepC_slides_oct2011.pdf Source: https://freecomputerbooks.com/Deep-C-and-Cpp.html#downloadLi... Previous discussion: https://news.ycombinator.com/item?id=3093323 It could be considered a bit dated at this point (It's before C++11) but I find it still both entertaining and educating.
Mildly interesting quirks of C
51–60 of 91 posts
Re: Mildly interesting quirks of C
#52Can someone explain how "A constant-expression macro that tells you if an expression is an integer constant" works ?
If `x` is not a constant, `(void*)((x) * 0l)` is a void pointer to address 0 (which may not even be a null pointer at runtime, since null may have a runtime address distinct from zero!). The ternary conditional then unifies the types of the branches, resulting in `void*`.
Re: Mildly interesting quirks of C
#53Re: Mildly interesting quirks of C
#54Reminds me a bit of "Who Says C is Simple?" written by the people who wrote a C parser & analyser in OCaml (CIL): https://cil-project.github.io/cil/doc/html/cil/cil016.html Also: https://cil-project.github.io/cil/doc/html/cil/cil012.html
> "Who Says C is Simple?" People who don't know what "simple" means and confuse it with "easy". https://www.entropywins.wtf/blog/2017/01/02/simple-is-not-ea... https://www.infoq.com/presentations/Simple-Made-Easy/ "Easy" things almost always lead to astonishing complexity. Also it's easy to see just how complex C is: Have a look at a formal description of it! (And compare to a truly simple language like e.g. LISP). h…
"simplicity is the ultimate sophistication." -- Leonardo da Vinci
Re: Mildly interesting quirks of C
#55The "compound literals are lvalues" pattern I've seen many times for inline initializing a struct that's only going to be around as a parameter to a single function call.
Re: Mildly interesting quirks of C
#56Earlier quoted context omitted.
I really wish both would be valid in C11. Or rather I wish I had "systems-C" where all the undefined behaviour added for high performance computing was filed off and defined as "whatever the platform does".
> all the undefined behaviour added for high performance computing UBs were added for cross-incompatibilities, where operations were too "core" (and / or untestable) for IBs to be acceptable. The reason was not performance (aside from not imposing a runtime check where that would have been possible) but portability: > 3.4.3 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of er…
Re: Mildly interesting quirks of C
#57> UB is impossible What? UB is clearly undesirable , but assuming it is impossible and deducing other outcomes must be meant are clearly wrong assumptions by the compiler writer. More sensible compilers (including older version of clang) do the right thing (TM) here and yield a compiler error. There were earlier attempts at do-what-i-mean programming languages. They are rightfully buried in history.
Compilers can and absolutely do assume that UB is impossible in this code (no integer overflow) and deduce other outcomes must be meant (the loop operates on contiguous memory):
void foo(char* arr, int32_t end)
{
for (int32_t i = 0; i != end; ++i)
arr[i] = 0;
}
(Based on code from the gist comments.)Re: Mildly interesting quirks of C
#58My favorite C "quirk": If you have an array and you want to access an item of it, you can swap the variable and the index number (put the variable name inside brackets and the number outside): a[5] is the same as: 5[a] why? a[5] is actually sugar for *(a + 5), so by commutative property, you can also do *(5 + a) to access the same memory position :-)
Array-to-pointer decay is another manifestation of this.
Re: Mildly interesting quirks of C
#59Regarding 12, alignment of bitfields, how I believe it works is that when the bitfield of type long is laid out, then the structure so far is considered to be a vector of storage cells whose size and alignment are those of long: struct foo { char a; long b: 16; char c; }; So, a has been laid into the structure, so the current offset is 1 byte. This is considered to be occupying a portion of an existing long type bitf…
Re: Mildly interesting quirks of C
#60Here are two of my favorite obscure quirks of C: struct X { char x[8]; }; struct X awoo(void); printf("%s\n", awoo().x); The above is UB in = C11. [0] struct X { char b[8]; } foo(); int *b = foo().b; printf("%s\n", b); The above is UB in >= C11 and valid in [0] https://wiki.sei.cmu.edu/confluence/plugins/servlet/mobile?c... [1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1285.htm
I really wish both would be valid in C11. Or rather I wish I had "systems-C" where all the undefined behaviour added for high performance computing was filed off and defined as "whatever the platform does".