An article on C structure packing without any mention of __attribute__((__packed__))?? meh.
He mentioned it in passing (and without proper syntax) in section 11.
81–90 of 116 posts
An article on C structure packing without any mention of __attribute__((__packed__))?? meh.
He mentioned it in passing (and without proper syntax) in section 11.
Earlier quoted context omitted.
The language spec prevents it from doing so for ABI reasons. The optimization is present in other languages that did not start with this restriction, but it's too late for C now.
>The optimization is present in other languages that did not start with this restriction, but it's too late for C now. Which? .NET is the only one I could find that appears to do some from of smart packing [1] The new hotness languages behave like: Go doesn't sort by size. It packs to the byte, but guarantees structures within structures will start on the 32/64bit boundary (depending on 32/64bit system) so it'll pad…
However:
since shipping the first version of this guide I have been asked why, if reordering for minimal slop is so simple, C compilers don’t do it automatically. The answer: C is a language originally designed for writing operating systems and other code close to the hardware. Automatic reordering would interfere with a systems programmer’s ability to lay out structures that exactly match the byte and bit-level layout of memory-mapped device control blocks.
If the programmer wants or needs absolute control, just do not provide the reordering option to the optimizing compiler. So why wouldn't compilers provide a command line option to do automatic reordering?
ESR is a good programmer, and this is a handy guide for those who don't know how to pack structures. He's also insane, so don't trust anything he says. Oh, you don't think he's insane? He thinks there's a conspiracy amongst women in open source to discredit Linus Torvalds. No, I'm not joking. I wish I was.
Earlier quoted context omitted.
> The worst that you will get is padding at the end of the structure so that if two or more of them are arrayed, the first member is correctly aligned at all the array indices. This is not guaranteed. If you want to ensure all array member starting addresses are aligned for all compilers and platforms you need to add explicit dead space. You should also be using the fixed-width numeric types.
It's not guaranteed (as in "money back" or whatever). It's merely required by ISO C for conformance. If a struct is declared like this: struct foo { whatever_type_t first_member; // ... }; then an array of this type can also be declared: struct foo farray[42]; A conforming ISO C implementation has to ensure that farray[1].first_member, and farray[2].first_member, and so on, are all allocated such that they meet the a…
uint32_t and friends instead of the implementation-defined unsigned int/long.
See http://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdi... for many details (including things like the name for "the fastest signed integer type with at least 8 bits", which could be signed char on machines that support byte access in hardware and signed 32-bit on machines where byte addressing means loading a word, bit-bashing the new value in, and storing it back).
The bit-field feature of C structs is underutilized. People are still writing hex constants and using AND and OR to clear and set bits. Let the compiler do that; it's more readable. As of C99, there's named structure initialization, which makes bitfield constants more readable.
Earlier quoted context omitted.
The language spec prevents it from doing so for ABI reasons. The optimization is present in other languages that did not start with this restriction, but it's too late for C now.
>The optimization is present in other languages that did not start with this restriction, but it's too late for C now. Which? .NET is the only one I could find that appears to do some from of smart packing [1] The new hotness languages behave like: Go doesn't sort by size. It packs to the byte, but guarantees structures within structures will start on the 32/64bit boundary (depending on 32/64bit system) so it'll pad…
Earlier quoted context omitted.
What if your struct is actually a memory-mapped I/O device? Far from optimizing you need to give a hard guarantee that it will NEVER be optimized by the compiler.
Suppose C didn't require order of struct members. How could we support I/O devices? Simply by wrapping them behind functions or macros which take a base address and access a specific register relative to that address using pointer arithmetic and dereferencing. You see this being done anyway! if ((SERIAL_STATUS_PORT(port_addr) & SERIAL_DTR) != 0) { /* DTR line is asserted */ }
You see in a lot of high performance networking code too, you just get a block of bytes off the wire, cast it to a struct and use it straight away. High risk, high reward :-)
Earlier quoted context omitted.
Alright this might be a stupid question, but if packing is about the order in which the fields are arranged... shouldn't the compiler optimize that? I mean, it does much more complex optimizations already doesn't it?
Structs get written directly to disk and network. Copies of the same program would produce different output depending on the optimization strategy they were compiled with. That's vigorously not allowed.