[cfe-dev] 'struct' member alignment query

Martin J. O'Riordan via cfe-dev cfe-dev at lists.llvm.org
Thu Feb 9 02:56:04 PST 2017


Our architecture has fairly conventional data layout rules, with:

  o  8-bit, byte aligned 'char'              (int8_t)
  o  16-bit, 2-byte aligned 'short'          (int16_t)
  o  32-bit, 4-byte aligned 'int' and 'long' (int32_t)
  o  64-bit, 8-byte aligned 'long long'      (int64_t)

However, I wanted to experiment with 'struct's that internally have
self-consistent member alignment, but which deliberately map a 'struct'
member of another 'struct' onto a boundary that is not consistent with the
member 'struct's desired alignment.

The test I am using is appended (it is a C file), and the line in this that
I have a question about is #21:

    AlignCheck_t alignCheck2 __attribute__((aligned(1)));  // Should have an
alignment of 1-Byte???

where I have tried to override the default alignment for the aggregate
member, but the '__attribute__((aligned(1)))' does not appear to have any
effect and the member is padded in the normal way, and so fails with the
test at line #64.

Is this expected behaviour in 'clang', and if so, is there another way I can
coerce the 'struct' member 'alignCheck2' onto another less constrained
alignment boundary?

Thanks,

	MartinO

---------- alignmentCheck.c ----------
#include <stdio.h>
#include <stddef.h>

typedef struct AlignCheck_t {
   char  a;         // 0:    [a]
                    // 1:    [X-X-X]   padding
   int   b;         // 4:    [b-b-b-b]
   char  c;         // 8:    [c]
                    // 9:    [X]       padding
   short d;         // 10:   [d-d]
   char  e;         // 12:   [e]
                    // 13:   [X-X-X]   padding
   long long  f[2]; // 16:   [f-f-f-f-f-f-f-f][f-f-f-f-f-f-f-f]
} AlignCheck_t;

typedef struct Group_t {
    char         dummy1;                                   // Should have an
alignment of 1-Byte
    AlignCheck_t alignCheck1;                              // Should have an
alignment of 8-Bytes

    char         dummy2;                                   // Should have an
alignment of 1-Byte
    AlignCheck_t alignCheck2 __attribute__((aligned(1)));  // Should have an
alignment of 1-Byte???

    char         dummy3;                                   // Should have an
alignment of 1-Byte
} Group_t;

char dummy0;                                               // Should have an
alignment of 1-Byte
Group_t alignedGroup = {
                            1,
                           {  2,  3,  4,  5,  6,  7ll },
                           11,
                           { 12, 13, 14, 15, 16, 17ll },
                           21
                       };

int main( void )
{
    int failed = 0;
    unsigned check1 = (unsigned)&alignedGroup.dummy1;
    unsigned check2 = (unsigned)&alignedGroup.alignCheck1;
    unsigned check3 = (unsigned)&alignedGroup.dummy2;
    unsigned check4 = (unsigned)&alignedGroup.alignCheck2;
    unsigned check5 = (unsigned)&alignedGroup.dummy3;

    if (( check2 & 0x00000007 ) != 0 )
        failed = 1;
    else if ( offsetof ( AlignCheck_t, a ) != 0 )
        failed = 2;
    else if ( offsetof ( AlignCheck_t, b ) != 4 )
        failed = 3;
    else if ( offsetof ( AlignCheck_t, c ) != 8 )
        failed = 4;
    else if ( offsetof ( AlignCheck_t, d ) != 10 )
        failed = 5;
    else if ( offsetof ( AlignCheck_t, e ) != 12 )
        failed = 6;
    else if ( offsetof ( AlignCheck_t, f ) != 16 )
        failed = 7;
    else if ( sizeof ( AlignCheck_t ) != 32 )
        failed = 8;
    else if (( check2 - check1 ) != 8 )
        failed = 9;
    else if (( check3 - check2 ) != 32 )
        failed = 10;
    else if (( check4 - check3 ) != 1 )
        failed = 11;
    else if (( check5 - check4 ) != 32 )
        failed = 12;

    if ( failed )
        puts("\n\nAlignment check FAILED\n\n");
    else
        puts("\n\nAlignment check PASSED\n\n");

    return failed;
}





More information about the cfe-dev mailing list