Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce struct size alignment

Is there a way to force the size of a struct to be a multiple of the maximum required alignment for any type? Here are two different attempts:

#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>

typedef struct {
    char c;
} Block1;

typedef struct {
    char c;
    max_align_t data[];
} Block2;

typedef struct {
    char c;
    _Alignas(sizeof(max_align_t)) max_align_t data[];
} Block3;

int
main() {
    printf("sizeof(max_align_t): %zu\n", sizeof(max_align_t));
    printf("sizeof(Block1): %zu\n", sizeof(Block1));
    printf("sizeof(Block2): %zu\n", sizeof(Block2));
    printf("sizeof(Block3): %zu\n", sizeof(Block3));
}

With gcc 4.9.2 on a 64-bit machine I get this, so Block3 seems to work. Interestingly, Block2 does not work, though I can guess why:

sizeof(max_align_t): 32
sizeof(Block1): 1
sizeof(Block2): 16
sizeof(Block3): 32

Just wondering whether or not Block3 is guaranteed to work (by the C11 standard), and whether or not there is a better way.

ADDENDUM: Apparently, I misinterpreted the meaning of max_align_t. I thought that sizeof(max_align_t) gives the maximum required alignment of any scalar type, but apparently it's _Alignof(max_align_t) that gives this. So Block2 actually works.

like image 468
kec Avatar asked Jan 24 '26 11:01

kec


1 Answers

Is there a way to force the size of a struct to be a multiple of the maximum required alignment?

Well, if you meant the maximum alignment for its elements, that's always trivially the case. You are done.

If instead you mean some fundamental alignment,

  1. use _Alignas(type) on a member (you cannot accidentally lower the alignment-requirements this way).
  2. use a member of a type aligned like above. Your second example uses a flexible-array-member doing so.

max_align_t has the maximum fundamental alignment.

If instead you mean some extended alignment, _Alignas(power_of_two) is your friend (unsupported alignments must be diagnosed), though there is no guarantee over-aligned types are supported at all.
Nor is there any way to query the maximum supported extended alignment.

6.2.8 Alignment of objects

1 Complete object types have alignment requirements which place restrictions on the addresses at which objects of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type: stricter alignment can be requested using the _Alignas keyword.
2 A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to _Alignof (max_align_t).
3 An extended alignment is represented by an alignment greater than _Alignof (max_align_t). It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type.57)
4 Alignments are represented as values of the type size_t. Valid alignments include only those values returned by an _Alignof expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. Every valid alignment value shall be a nonnegative integral power of two.
5 Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
6 The alignment requirement of a complete type can be queried using an _Alignof expression. The types char, signed char, and unsigned char shall have the weakest alignment requirement.
7 Comparing alignments is meaningful and provides the obvious results:

  • Two alignments are equal when their numeric values are equal.
  • Two alignments are different when their numeric values are not equal.
  • When an alignment is larger than another it represents a stricter alignment.
like image 139
Deduplicator Avatar answered Jan 26 '26 01:01

Deduplicator