Live data from Hacker News

Mildly interesting quirks of C

gist.github.com

11–20 of 91 posts

Re: Mildly interesting quirks of C

#11
Another one, adhoc struct declaration in the return type of a function:

    struct bla_t { int a, b, c, d; } make_bla(void) {
        return (struct bla_t){ .a=1, .b=2, .c=3, .d=4 };
    }
https://www.godbolt.org/z/Pha7dPzeq

Also to be pedantic: "= {};" is not valid C (at least until C23) and fails to compile on MSVC - GCC and Clang accept it as a non-standard language extension though (the proper form would be "= {0};").

Re: Mildly interesting quirks of C

#12
Regarding 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 bitfield cell. In other words a is essentially taken to be an 8-bit field in the first long-sized cell of the structure. That cell looks like it has 56 bits left in it (if we assume 64 bit long). Since 56 > 16, the new bitfield b is placed into that cell. When that field is placed, the placement offset becomes 3. The type of c being char, that offset is acceptable for c.

I've painstakingly reverse engineered the rules when developing the FFI for TXR Lisp:

  1> (sizeof (struct foo (a char) (b (bit 16 long)) (c char)))
  8
  2> (alignof (struct foo (a char) (b (bit 16 long)) (c char)))
  8
  3> (offsetof (struct foo (a char) (b (bit 16 long)) (c char)) a)
  0
  4> (offsetof (struct foo (a char) (b (bit 16 long)) (c char)) b)
  ** ffi-offsetof: b is a bitfield in #
  4> (offsetof (struct foo (a char) (b (bit 16 long)) (c char)) c)
  3
I've summarized my empirically-obtained understanding for the benefit of users and anyone else doing similar work in a different project.

https://www.nongnu.org/txr/txr-manpage.html#N-027D075C

Re: Mildly interesting quirks of C

#14
post #3

While a few of these were interesting I'd love to see a short technical explanation of each quirk for the feeble high-level programmer (me). The first one for example, is foo initialised? How so?

The reason is that a struct doesn't generate a new scope, like in C++. If you define something inside a struct it will also be available outside of the struct.

Re: Mildly interesting quirks of C

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

Re: Mildly interesting quirks of C

#16
My 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 :-)

Re: Mildly interesting quirks of C

#18
post #16

My 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 :-)

That's #15 on the list.

Re: Mildly interesting quirks of C

#19
Here 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

Re: Mildly interesting quirks of C

#20

Here 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".
Post reply on HN