5
#define MAX_SIZE 8

enum my_enum
{
    VAL1 = 0;
    VAL2,
    VAL3,
    VAL4,
    VAL_MAX
};

struct my_struct
{
  enum my_enum e;
  int  w[MAX_SIZE];
};

Can a layout in such structure cause alignment issues on a target platform? I understand it much depends on a platform, but generally C compiler is allowed to do padding of structures, so for example on 32 bit machine, where 'int' is 32 bit long:

struct my_struct
{
    int w[MAX_SIZE];
}

is aligned (as fas as I understand) so compiler probably won't be doing anything else with its layout, but adding 'enum my_enum' in the structure can poptentially get the structure un-aligned on such machine. Should I be doing anything special to avoid this and should I be avoiding it at all ?

Would be very thankful for clarifications!

Mark

Mark
  • 6,052
  • 8
  • 61
  • 129
  • 1
    You do need to worry if you assume the struct is merely the sum of elements. For example `struct my_struct *p = malloc(sizeof(my_enum)+n*sizeof(int))` attempts to allocate fewer than `MAX_SIZE` ints. But if there's padding, you end up allocating too little. – ugoren Jan 11 '12 at 19:21

3 Answers3

6

The answer is no, you don't have to do anything. If adding a field will break alignment, the compiler will apply padding in the appropriate places to realign it.

In your case, enums are likely to be implemented as an int so you wouldn't have this problem in the first place.

A better example would be:

struct my_struct
{
  char ch;
  int  w[MAX_SIZE];
};

In this case, the compiler will likely place 3 bytes of padding after ch to keep w aligned to 4 bytes.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
0

You do not need to be concerned about trying not to introduce padding. If you want to experiment with a demonstration of how the order of structure-members might or might not make a difference, you can try this. (It's not intended to demonstrate how a particular implementation behaves.)

According to the C11 standard, all alignments are powers of two.

Simple mathematics dictates that it's not possible for an object's alignment requirement to exceed its size, unless it's also impossible to create an array of such objects.

synthetel
  • 63
  • 5
0

No, you don't have to think about alignment in a "does it work" sense. Basically it's up to the compiler to align things to work for the target platform. If it's smart it will even do it in the way that allows for the greatest performance.

For example, if you have a char first, then an integer and the target platform allows for unaligned load/store, the compiler may generate the structure as 5 bytes in size with the integer being unaligned. If you want to guarantee 4 byte alignment, you'd need to do

struct my_struct {
  char a;
  char dummy[3];
  int b;
}

or put the datatypes from largest to smallest in the structure to get the best performance.

Edit: It has been pointed out to me that the specification may have tightened up around this behavior, so most if not all modern compilers now align everything on natural boundaries.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • A compiler may or may not align members on "natural" boundaries. It *must* align all members in such a way that they can be accessed properly. For example, given `struct my_struct obj; int *ptr = &obj.b;`, references to `*ptr` must work. (Compiler-specific packing pragmas and attributes can break this; see [this question](http://stackoverflow.com/questions/8568432/is-gccs-attribute-packed-pragma-pack-unsafe), for example.) – Keith Thompson Jan 11 '12 at 22:14