How do you mean that a byte array is added? Because at least in my experiments, I don’t see that:
struct A
{
int a;
char b;
long c;
};
struct A a;
produces:
; ModuleID = ‘pad.c’
target datalayout = “e-m:e-i64:64-f80:128-n8:16:32:64-S128”
target triple = “x86_64-unknown-linux-gnu”
%struct.A = type { i32, i8, i64 }
@a = common global %struct.A zeroinitializer, align 8
!llvm.ident = !{!0}
Adding a call to printf,
extern int printf(const char fmt, …);
void func(struct A a)
{
printf(“c=%ld”, a->c);
}
and outputting assembler, we can see that the offset to “c” in that struct is 8:
func: # @func
.cfi_startproc
BB#0: # %entry
movq 8(%rdi), %rsi
movl $.L.str, %edi
xorl %eax, %eax
jmp printf # TAILCALL
So, can you provide an example of this padding, because I don’t see it. This is clang 3.8, but 3.9 did the same thing (I went back to 3.8 to check if it was different)
There will be padding in the actual data structure, based on the need for aligning (better performance if not required by the hardware), so if we for example initalize the data:
struct A a = { 3, ‘a’, 4711 };
then there will be LLVM-code like this:
@a = global %struct.A { i32 3, i8 97, i64 4711 }, align 8
and in the machine code there will be:
a:
.long 3 # 0x3
.byte 97 # 0x61
.zero 3
.quad 4711 # 0x1267
Because three bytes of zeros are needed to fill the data between the ‘a’ and the long of 4711. But nowhere other than in the machine-code is that padding anything more than “difference between theoretical closest offset and aligned offset”.