1

I am working on a memory allocator. Each allocated buffer starts on an 8-byte boundary and each is preceded by a header for managing the allocation (the header is immediately before the 8-byte-aligned buffer).

The header looks like:

struct header {
    uint32_t     hword32;
    void        *hpointer;
};

Assuming that all members of this structure are packed and that a pointer is 64-bit, this structure has a length of 12 bytes and the alignment of each member is correct (because the end of the structure is 8-byte-aligned).

Accordingly, I would like to tell my compiler two things:

  1. Do not add padding between the two members of the structure; and
  2. Don’t worry, about the alignment of the members, they are aligned.

How can I do this with gcc?

It is tempting to use __attribute__((packed)). However, while this does the trick for 1., my understanding is that it does not cover 2. (i.e. it causes the compiler to insert code to handle unaligned accesses, which is not needed here).

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Philippe Aubertin
  • 1,031
  • 1
  • 9
  • 22
  • 2
    You could add `uint32_t padding;` at the beginning of the structure. – melpomene Jul 28 '18 at 19:16
  • 1
    I suspect melpomene’s suggestion to prefix padding may be necessary because a 12-byte structure with an 8-byte alignment requirement contrasts fundamentally with C’s requirement that the size of an object be suitable for making an array of them. Implementations provide extensions like attributes to modify certain things, but note that `packed` makes a simple change (weaken the alignment requirements of these members) that fits into the language (other rules about arrays, alignment, and so on still apply). The objectives of the question strain the rules. – Eric Postpischil Jul 28 '18 at 19:43
  • https://godbolt.org/g/QkcKBQ I do not see any aditional code here – 0___________ Jul 28 '18 at 19:59
  • 1
    @P__J__ x86 processors handle unaligned access transparently (although possibly with a performance penalty). However, many architectures (e.g. ARM and SPARC) require accesses to be aligned and either raise a processor exception or silently load the wrong data if they aren't. – Philippe Aubertin Jul 28 '18 at 20:11
  • @PhilippeAubertin: As I recall, enforcing alignment constraints is configurable in current and recent x86 processors and also varies with instruction and data type combinations. (For example, old floating-point loads may allow unaligned while SSE loads do not.) So a blanket statement like that is questionable. The reason P__J__’s exploratory code did not generate extra instructions would be due to their compiler version and switches, not the inherent nature of x86 processors. – Eric Postpischil Jul 28 '18 at 20:32
  • By far the simplest technique is not to worry about the space used. Or increase the header to a `uint64_t`. Or don't futz with the packing, because then the compiler doesn't have to worry about condition 2 because it is accurate. Your premise that condition 2 is true for the 12-byte structure is wrong on many types of machines. Of course, that means forgoing condition 1 (unless you put the pointer first; then there'll be no padding between the members, but there might be trailing padding on 64-bit platforms). – Jonathan Leffler Jul 28 '18 at 20:33

0 Answers0