Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #168144 > unrolled thread

_Alignof structs

Started byThiago Adams <thiago.adams@gmail.com>
First post2022-11-10 10:50 -0800
Last post2022-11-13 18:44 -0800
Articles 11 — 7 participants

Back to article view | Back to comp.lang.c


Contents

  _Alignof structs Thiago Adams <thiago.adams@gmail.com> - 2022-11-10 10:50 -0800
    Re: _Alignof structs Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-11-10 11:56 -0800
      Re: _Alignof structs Thiago Adams <thiago.adams@gmail.com> - 2022-11-11 02:57 -0800
        Re: _Alignof structs Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-11-11 15:07 -0800
          Re: _Alignof structs Thiago Adams <thiago.adams@gmail.com> - 2022-11-11 18:08 -0800
    Re: _Alignof structs Richard Damon <Richard@Damon-Family.org> - 2022-11-11 22:09 -0500
    Re: _Alignof structs Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-11-11 19:22 -0800
      Re: _Alignof structs Thiago Adams <thiago.adams@gmail.com> - 2022-11-12 02:53 -0800
        Re: _Alignof structs Po Lu <luangruo@yahoo.com> - 2022-11-14 10:28 +0800
          Re: _Alignof structs Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-11-14 02:44 +0000
            Re: _Alignof structs "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-11-13 18:44 -0800

#168144 — _Alignof structs

FromThiago Adams <thiago.adams@gmail.com>
Date2022-11-10 10:50 -0800
Subject_Alignof structs
Message-ID<2aa493b5-e975-42f8-bc98-f35a7f797159n@googlegroups.com>
What is the idea behind alignof structs?

I tried this code in gcc

struct X {
    char i;
    char s;
};
_Static_assert(_Alignof(struct X) == 1, "");

int main(){}

The result seems to be the alignof the first element of struct.
Changing i for int or double changes the ouput.
I was expecting the max alignment before checking it.

[toc] | [next] | [standalone]


#168145

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-11-10 11:56 -0800
Message-ID<87wn82lh11.fsf@nosuchdomain.example.com>
In reply to#168144
Thiago Adams <thiago.adams@gmail.com> writes:
> What is the idea behind alignof structs?
>
> I tried this code in gcc
>
> struct X {
>     char i;
>     char s;
> };
> _Static_assert(_Alignof(struct X) == 1, "");
>
> int main(){}
>
> The result seems to be the alignof the first element of struct.
> Changing i for int or double changes the ouput.
> I was expecting the max alignment before checking it.

I'm not sure why you'd expect the max alignment.

gcc could have required 2-byte alignment for struct X (or even a 4-byte
alignment with padding bytes after the last member), but it allows a
struct X object to be at any byte boundary.

The alignment for a structure is at least the maximum alignment of any
of its members.  If all the members are single bytes, the structure
alignment can be 1 or it can be more strict, at the whim of the compiler
(probably guided by some ABI).  And if a struct X is allocated at an odd
address, the compiler does whatever is needed to make it work.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#168146

FromThiago Adams <thiago.adams@gmail.com>
Date2022-11-11 02:57 -0800
Message-ID<95c1d6a3-a3d9-4ec4-ab5d-56b68cfde119n@googlegroups.com>
In reply to#168145
On Thursday, November 10, 2022 at 4:57:12 PM UTC-3, Keith Thompson wrote:
> Thiago Adams <thiago...@gmail.com> writes: 
> > What is the idea behind alignof structs? 
> > 
> > I tried this code in gcc 
> > 
> > struct X { 
> > char i; 
> > char s; 
> > }; 
> > _Static_assert(_Alignof(struct X) == 1, ""); 
> > 
> > int main(){} 
> > 
> > The result seems to be the alignof the first element of struct. 
> > Changing i for int or double changes the ouput. 
> > I was expecting the max alignment before checking it.
> I'm not sure why you'd expect the max alignment. 

I  was expecting a fixed the max alignment to be possible to 
have a fixed reference for padding. The way I think it works (with padding) 
is to have each member positioned on it own alignment. 
I am trying to see now (thinking in some samples), if placing struct at the
max member aligment will result in each member on its own aligment (considering padding)

[toc] | [prev] | [next] | [standalone]


#168148

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-11-11 15:07 -0800
Message-ID<87sfipks3i.fsf@nosuchdomain.example.com>
In reply to#168146
Thiago Adams <thiago.adams@gmail.com> writes:
> On Thursday, November 10, 2022 at 4:57:12 PM UTC-3, Keith Thompson wrote:
>> Thiago Adams <thiago...@gmail.com> writes: 
>> > What is the idea behind alignof structs? 
>> > 
>> > I tried this code in gcc 
>> > 
>> > struct X { 
>> > char i; 
>> > char s; 
>> > }; 
>> > _Static_assert(_Alignof(struct X) == 1, ""); 
>> > 
>> > int main(){} 
>> > 
>> > The result seems to be the alignof the first element of struct. 
>> > Changing i for int or double changes the ouput. 
>> > I was expecting the max alignment before checking it.
>> I'm not sure why you'd expect the max alignment. 
>
> I  was expecting a fixed the max alignment to be possible to 
> have a fixed reference for padding. The way I think it works (with padding) 
> is to have each member positioned on it own alignment. 
> I am trying to see now (thinking in some samples), if placing struct at the
> max member aligment will result in each member on its own aligment (considering padding)

I don't understand.

For this structure, no padding is necessary, and the members can be
accessed correctly regardless of the alignment of the structure.  The
maximum alignment of any member is 1 (char is 1 byte, and char arrays
wouldn't work if char required a stricter alignment), which means that
the alignment of the struct has to be *at least* 1.

What exactly do you mean by "max alignment", and why are you expecting
it to be something other than 1?

I wouldn't have been surprised of the alignment of the structure had
been 2, but gcc chooses to give it a 1-byte alignment, likely because
the relevant ABI requires it.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#168149

FromThiago Adams <thiago.adams@gmail.com>
Date2022-11-11 18:08 -0800
Message-ID<f089f34b-c278-44ad-b411-6a33124a88d7n@googlegroups.com>
In reply to#168148
On Friday, November 11, 2022 at 8:08:03 PM UTC-3, Keith Thompson wrote:
> Thiago Adams <thiago...@gmail.com> writes: 
> > On Thursday, November 10, 2022 at 4:57:12 PM UTC-3, Keith Thompson wrote: 
> >> Thiago Adams <thiago...@gmail.com> writes: 
> >> > What is the idea behind alignof structs? 
> >> > 
> >> > I tried this code in gcc 
> >> > 
> >> > struct X { 
> >> > char i; 
> >> > char s; 
> >> > }; 
> >> > _Static_assert(_Alignof(struct X) == 1, ""); 
> >> > 
> >> > int main(){} 
> >> > 
> >> > The result seems to be the alignof the first element of struct. 
> >> > Changing i for int or double changes the ouput. 
> >> > I was expecting the max alignment before checking it. 
> >> I'm not sure why you'd expect the max alignment. 
> > 
> > I was expecting a fixed the max alignment to be possible to 
> > have a fixed reference for padding. The way I think it works (with padding) 
> > is to have each member positioned on it own alignment. 
> > I am trying to see now (thinking in some samples), if placing struct at the 
> > max member aligment will result in each member on its own aligment (considering padding)
> I don't understand. 
> 
> For this structure, no padding is necessary, and the members can be 
> accessed correctly regardless of the alignment of the structure. The 
> maximum alignment of any member is 1 (char is 1 byte, and char arrays 
> wouldn't work if char required a stricter alignment), which means that 
> the alignment of the struct has to be *at least* 1. 
> 
> What exactly do you mean by "max alignment", and why are you expecting 
> it to be something other than 1? 

Same returned by malloc.

 
> I wouldn't have been surprised of the alignment of the structure had 
> been 2, but gcc chooses to give it a 1-byte alignment, likely because 
> the relevant ABI requires it.
> -- 



I think it is more clear to me now. I played with compiler explorer C++ mode
msvc compiler and /d1reportSingleClassLayoutCLASSNAME

for instance
struct X{
    char s;
    double c;
    char s2;
    }

https://godbolt.org/z/T9T8538Kh

prints

class X	size(24):
	+---
 0	| s
  	| <alignment member> (size=7)
 8	| c
16	| s2
  	| <alignment member> (size=7)
	+---


The bigger element defines the struct alignment.


struct X{
    char s;
    struct Y {char s2; int i;} d;
    double c;    
    char s2;
    };

class X	size(32):
	+---
 0	| s
  	| <alignment member> (size=3)
 4	| Y d
  	| <alignment member> (size=4)
16	| c
24	| s2
  	| <alignment member> (size=7)
	+---


struct X{
    char s;
    struct Y {char s2; double i;} d;
    double c;
    
    char s2;
    }
    ;
prints

class X	size(40):
	+---
 0	| s
  	| <alignment member> (size=7)
 8	| Y d
24	| c
32	| s2
  	| <alignment member> (size=7)
	+---


struct X{
    char c;
    short s;
    }
    ;
class X	size(4):
	+---
 0	| c
  	| <alignment member> (size=1)
 2	| s
	+---
so...if the alignment of this last struct is 2..it can be placed in address divisible by
2 or 4 or 8 .but no divisible by 1. 

for instance , like 13, because in this case 's' would be at 13+2=15
that is  not aligned for short.


changing 's' from short to int the struct can be placed in address divisible 
by 4 or 8. so address 14 for instance is not allowed.

[toc] | [prev] | [next] | [standalone]


#168150

FromRichard Damon <Richard@Damon-Family.org>
Date2022-11-11 22:09 -0500
Message-ID<w7EbL.106889$U709.47977@fx16.iad>
In reply to#168144
On 11/10/22 1:50 PM, Thiago Adams wrote:
> What is the idea behind alignof structs?
> 
> I tried this code in gcc
> 
> struct X {
>      char i;
>      char s;
> };
> _Static_assert(_Alignof(struct X) == 1, "");
> 
> int main(){}
> 
> The result seems to be the alignof the first element of struct.
> Changing i for int or double changes the ouput.
> I was expecting the max alignment before checking it.
> 

The key point is that the alignment of a structure needs to be AT LEAST 
as strict as the alignment of the strictest member, but might need to be 
stricter.

In fact, for some machines it might need to be, because another rule is 
that the representation of a pointer to a sturcture must be known 
without knowing the definition of the structure, so if your machine uses 
different representation pointers (like a machine that natively 
addresses bigger than byte chunks) the implementation needs to pick one 
for all structure pointers, and normally chooses the one which is more 
natural, even if it has a stricter alignment requirement then a more 
general format.

Sometimes, even if this isn't an issue, sometimes the compiler will 
still use a stricter alignment if it makes some operation easier.

For instance, for the above structure, it might use an alignment of 2, 
so that an assignment of one object of this type to another could use a 
two byte load and store instruction to be quicker and shorter instead of 
two seperate 1 byte operations.

[toc] | [prev] | [next] | [standalone]


#168151

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2022-11-11 19:22 -0800
Message-ID<tkn3i0$13e3m$1@dont-email.me>
In reply to#168144
On 11/10/2022 10:50 AM, Thiago Adams wrote:
> What is the idea behind alignof structs?
> 
> I tried this code in gcc
> 
> struct X {
>      char i;
>      char s;
> };
> _Static_assert(_Alignof(struct X) == 1, "");
> 
> int main(){}
> 
> The result seems to be the alignof the first element of struct.
> Changing i for int or double changes the ouput.

That's bizarre. A natural thing to expect would be maximum _Alignof 
among all members. How you managed to get _Alignof of the _first_ 
element specifically is not clear to me. I just tried it in gcc and it 
worked as expected: maximum _Alignof among all members.

> I was expecting the max alignment before checking it.

What do you mean by "max alignment"? `_Alignof(max_align_t)` or what I 
describe above?

-- 
Best regards,
Andrey

[toc] | [prev] | [next] | [standalone]


#168157

FromThiago Adams <thiago.adams@gmail.com>
Date2022-11-12 02:53 -0800
Message-ID<5ee95e61-ccca-4863-af55-c04973ccfac3n@googlegroups.com>
In reply to#168151
On Saturday, November 12, 2022 at 12:22:53 AM UTC-3, Andrey Tarasevich wrote:
> On 11/10/2022 10:50 AM, Thiago Adams wrote: 
> > What is the idea behind alignof structs? 
> > 
> > I tried this code in gcc 
> > 
> > struct X { 
> > char i; 
> > char s; 
> > }; 
> > _Static_assert(_Alignof(struct X) == 1, ""); 
> > 
> > int main(){} 
> > 
> > The result seems to be the alignof the first element of struct. 
> > Changing i for int or double changes the ouput.
> That's bizarre. A natural thing to expect would be maximum _Alignof 
> among all members. How you managed to get _Alignof of the _first_ 
> element specifically is not clear to me. I just tried it in gcc and it 
> worked as expected: maximum _Alignof among all members.

>A natural thing to expect would be maximum _Alignof 
> among all members
I didn't know that. That was basically my question. So I tried and 
by coincidence I put the biggest align on the first element giving me
the wrong interpretation how it works.


> > I was expecting the max alignment before checking it.
> What do you mean by "max alignment"? `_Alignof(max_align_t)` or what I 
> describe above? 

Yes. the same aligment returned by malloc.

I was trying to understand how different align for structs
would result in the member by member correct aligment (considering padding)


(Sometimes I ask questions that may have the answer somewhere "google it", 
but I feel posting here will bring more details and maybe generate more insights)




[toc] | [prev] | [next] | [standalone]


#168172

FromPo Lu <luangruo@yahoo.com>
Date2022-11-14 10:28 +0800
Message-ID<87tu32i814.fsf@yahoo.com>
In reply to#168157
Thiago Adams <thiago.adams@gmail.com> writes:

> Yes. the same aligment returned by malloc.

Then you have to define a union of every built-in type, and take the
alignment of that union.

malloc does not know what type it is allocating memory for, so it
returns memory suitably aligned for *all* built-in types.

[toc] | [prev] | [next] | [standalone]


#168173

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-11-14 02:44 +0000
Message-ID<87k03yw8yo.fsf@bsb.me.uk>
In reply to#168172
Po Lu <luangruo@yahoo.com> writes:

> Thiago Adams <thiago.adams@gmail.com> writes:
>
>> Yes. the same aligment returned by malloc.
>
> Then you have to define a union of every built-in type, and take the
> alignment of that union.

Since C11, you can use max_align_t.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#168174

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2022-11-13 18:44 -0800
Message-ID<tksa3b$1lvpq$1@dont-email.me>
In reply to#168173
On 11/13/2022 6:44 PM, Ben Bacarisse wrote:
> Po Lu <luangruo@yahoo.com> writes:
> 
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>
>>> Yes. the same aligment returned by malloc.
>>
>> Then you have to define a union of every built-in type, and take the
>> alignment of that union.
> 
> Since C11, you can use max_align_t.
> 

Ding!

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web