In that particular example, it's because the WHOLE structure needs to be
aligned to 4 bytes, but the contents inside it is packed (because that's
what your attributes request - packed, and then align to 4).
So, yes, if you use attribute packed or attribute aligned to change the
natural alignment WITHIN a structure, then you will (if necessary) get
extra elements added to the struct. This largely because LLVM doesn't have
a (good) way to express this in a StructType.
Still don't understand what it is you are trying to do here. Definitely
something clang does, not something LLVM does. Also, I don't think you can
tell the difference between a manuall padded and an automatically padded
struct. Adding a char d[3]; to the struct with the packed,align 4
attribute, it produces the same type. The only difference is that it will
zero initialize `d`, where the anonymous padding is `undef` (allows the
compiler to optimise it away at times, I think).
--
Mats
On 18 May 2017 at 09:39, Hongbin Zheng <etherzhhb at gmail.com> wrote:
> the packed + aligned attribute will automatically introduce explicit
> padding byte array:
> https://godbolt.org/g/TlHX2g
>
> Sometimes Clang will decide to automatically pack the struct/class in C++,
> I don't know the details here, but looks like it is related to
inheritance.
>
> Thanks
> Hongbin
>
>
> On Thu, May 18, 2017 at 1:32 AM, mats petersson <mats at
planetcatfish.com>
> wrote:
>
>> 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".
>>
>> --
>> Mats
>>
>> On 18 May 2017 at 09:14, Hongbin Zheng <etherzhhb at gmail.com>
wrote:
>>
>>> Hi Mats,
>>>
>>> When the struct is packed, explicit byte array is introduced to pad
the
>>> struct. (I saw this happened in clang 3.9.)
>>>
>>> I want to check if a byte or byte array in an LLVM struct is
introduce
>>> for explicit padding or not.
>>>
>>> I don't need to worry about this problem in case the newest
clang do not
>>> introduce byte array anymore.
>>>
>>> Thanks
>>> Hongbin
>>>
>>> On Thu, May 18, 2017 at 1:03 AM, mats petersson <mats at
planetcatfish.com>
>>> wrote:
>>>
>>>> What are you actually trying to achieve? LLVM knows the
alignment and
>>>> size of each component. You could iterate over the different
types and
>>>> identify when there is a difference in "calculated total
size and the
>>>> current alignment requirement", but LLVM does
automatically pad structures
>>>> [unless you specifically ask it not to].
>>>>
>>>> Note that there is no actual field added for padding, it's
just the
>>>> size and alignment itself.
>>>>
>>>> --
>>>> Mats
>>>>
>>>> On 18 May 2017 at 08:51, Hongbin Zheng via cfe-dev <
>>>> cfe-dev at lists.llvm.org> wrote:
>>>>
>>>>> Hi Jonas,
>>>>>
>>>>> Thanks a lot.
>>>>> In an LLVM pass, how can I check the related information?
will clang
>>>>> emit some metadata table?
>>>>>
>>>>> Thanks
>>>>> Hongbin
>>>>>
>>>>> On Thu, May 18, 2017 at 12:47 AM, Jonas Devlieghere <
>>>>> jonas at devlieghere.com> wrote:
>>>>>
>>>>>> Hi Hongbin,
>>>>>>
>>>>>> You can pass `-Wpadded` to clang. For your particular
example it will
>>>>>> print something along the lines of
>>>>>>
>>>>>> ```
>>>>>> warning: padding struct 'foo1' with 7 bytes to
align 'x' [-Wpadded]
>>>>>> long x;
>>>>>> ```
>>>>>>
>>>>>> Jonas
>>>>>>
>>>>>> On Thu, May 18, 2017 at 9:15 AM, Hongbin Zheng via
llvm-dev <
>>>>>> llvm-dev at lists.llvm.org> wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I am wondering how I can tell whether a field of a
struct is
>>>>>>> introduced by padding or not.
>>>>>>>
>>>>>>> For example, if I have a struct:
>>>>>>>
>>>>>>> struct foo1 {
>>>>>>> char *p; /* 8 bytes */
>>>>>>> char c; /* 1 byte
>>>>>>> long x; /* 8 bytes */
>>>>>>> };
>>>>>>>
>>>>>>> clang may generate:
>>>>>>>
>>>>>>> struct foo1 {
>>>>>>> char *p; /* 8 bytes */
>>>>>>> char c; /* 1 byte
>>>>>>> char pad[7]; /* 7 bytes */
>>>>>>> long x; /* 8 bytes */
>>>>>>> };
>>>>>>>
>>>>>>> Is there any way that I can tell the
"pad" array is generated by
>>>>>>> padding?
>>>>>>>
>>>>>>> Thanks a lot
>>>>>>> Hongbin
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> LLVM Developers mailing list
>>>>>>> llvm-dev at lists.llvm.org
>>>>>>>
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> cfe-dev mailing list
>>>>> cfe-dev at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20170518/8b5865e4/attachment.html>