[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