Hacker News new | ask | show | jobs
by purple-leafy 538 days ago
But C/ C-compilers don't guarantee your struct wont have holes (by default), so you may have to do something like __attribute__((packed)) to ensure they are packed structs:

    struct bitmap_file_header
    {
      UWord signature;
      UDWord file_size;
      UWord reserved_1;
      UWord reserved_2;
      UDWord file_offset_to_pixel_array;
    } __attribute__((packed));
3 comments

This is not true of adjacent bitfields, at least for C99:

  An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf 6.7.2.1 § 10
That’s usually something your ABI will describe in fairly precise terms, though if (as in your example) you want non-naturally-aligned fields, you may indeed want to both use a packed struct and prepare for alignment faults on less-tolerant architectures.
There’s also a directive (don’t have code in front of me) that you can do at file level that will cause all subsequent struct defs to be packed…

#push(pragma(pack(0)) ??

I’ve done a lot of direct register access in C this way. I do like Zigs ability to just define the different sizes though.

It’s MS(V)C syntax, now supported by GCC and Clang as well:

  #pragma pack(push)
  #pragma pack(1)
  /* ... */
  #pragma pack(pop)
The first two lines can also be condensed into

  #pragma pack(push, 1)