Re: union.sizeof

2017-03-26 Thread zabruk70 via Digitalmars-d-learn

On Sunday, 26 March 2017 at 07:18:14 UTC, ketmar wrote:
i.e. what compiler does (roughly) is inserting anonymous fields 
of the appropriate size *into* the container. for "inner" 
aligning compiler inserts anonymous fields *between* other 
fields. for "outer" aligning compiler just appends anonymous 
field at the *end* of a data type, so data type size will met 
align requirements.


Big thank!!


Re: union.sizeof

2017-03-26 Thread ketmar via Digitalmars-d-learn

zabruk70 wrote:


On Sunday, 26 March 2017 at 06:45:13 UTC, ketmar wrote:

yes. you have a typo in second `writefln`: S1 instead of S2. ;-)


thank you.
another question, related to my first post:

why size of S2.b1 and S2.b2 still 3, not 4?

am i right: then align applied to members, compiler not change size of 
members, just make padding, so CONTAINER size changes?


yes. compiler is not allowed to mess with data types of the known size. ;-) 
and you are right: it doesn't have to. it just inserts dummy anonymous (and 
unused) bytes into struct/union to satisfy alignment requirements.




if so (because size of S2.b1 and S2.b2 still is 3 in my code),
then adding align(1) outside of union must not change zise of union, but 
size of some comainer more upper level.


nope, it changes size of the union itself. padding bytes *are* included in 
union, so `myunion.sizeof` includes 'em too.


i.e. what compiler does (roughly) is inserting anonymous fields of the 
appropriate size *into* the container. for "inner" aligning compiler 
inserts anonymous fields *between* other fields. for "outer" aligning 
compiler just appends anonymous field at the *end* of a data type, so data 
type size will met align requirements.


Re: union.sizeof

2017-03-26 Thread zabruk70 via Digitalmars-d-learn

On Sunday, 26 March 2017 at 06:45:13 UTC, ketmar wrote:

yes. you have a typo in second `writefln`: S1 instead of S2. ;-)


thank you.
another question, related to my first post:

why size of S2.b1 and S2.b2 still 3, not 4?

am i right: then align applied to members, compiler not change 
size of members, just make padding, so CONTAINER size changes?


if so (because size of S2.b1 and S2.b2 still is 3 in my code),
then adding align(1) outside of union must not change zise of 
union, but size of some comainer more upper level.


Re: union.sizeof

2017-03-26 Thread zabruk70 via Digitalmars-d-learn

On Sunday, 26 March 2017 at 06:38:59 UTC, zabruk70 wrote:

oh sorry sorry - mistyping

ok. DMD use padding, so for real container.sizeof
i should use lastMemeber.offsetof+lastMemeber.sizeof


Re: union.sizeof

2017-03-26 Thread ketmar via Digitalmars-d-learn

zabruk70 wrote:


On Sunday, 26 March 2017 at 05:09:15 UTC, ketmar wrote:

most of the time either location or padding will work the same.


hmm.. you ruined my expirence..

i made another experiment.
whould you please explain me S2 size 6?
thank you for you time.


yes. you have a typo in second `writefln`: S1 instead of S2. ;-)


Re: union.sizeof

2017-03-26 Thread zabruk70 via Digitalmars-d-learn

On Sunday, 26 March 2017 at 05:09:15 UTC, ketmar wrote:

most of the time either location or padding will work the same.


hmm.. you ruined my expirence..

i made another experiment.
whould you please explain me S2 size 6?
thank you for you time.

https://dpaste.dzfl.pl/9a31b6e370a0

struct S1 //sizeof=6
{
  align(1):
  byte[3] b1; //offsetof=0, sizeof=3
  byte[3] b2; //offsetof=3, sizeof=3
}

struct S2 //sizeof must be 7, but DMD say 6
{
  align(4):
  byte[3] b1; //offsetof=0, sizeof=3
  byte[3] b2; //offsetof=4, sizeof=3
}



Re: union.sizeof

2017-03-25 Thread ketmar via Digitalmars-d-learn

zabruk70 wrote:


Thank you ag0aep6g and ketmar!!

I will use additional outside align.
I want packing inside, you are right.
But i check result size with assert() and failed.

But for clearness...
I was thinked, that align not changes SIZE, but changes LOCATION.
I was thinked, that "align(X) union Union1"
just force compiler to place Union1 on boundaries of X bytes...


most of the time either location or padding will work the same. ;-)

but no, the idea of aligning is that structs/unions/etc. that comes 
together one after another are aligned from the starting offset of the 
first element, not from "address zero" for the whole app.


Re: union.sizeof

2017-03-25 Thread bauss via Digitalmars-d-learn

On Saturday, 25 March 2017 at 23:36:07 UTC, kinke wrote:

On Saturday, 25 March 2017 at 22:45:22 UTC, ketmar wrote:

zabruk70 wrote:


[...]


`align(1) union Union1` will do the trick.

what you did is members packing. but the union itself is 
padded to integer size too. i.e. internal `align` will set 
aligning for *members*, and external `align` will change 
padding of the whole thing.


The union should have an implicit alignment of 1 already 
though, right? It's defined as the maximum of all member 
alignments, and both the bytes5 array and the anonymous struct 
members have an explicit alignment of 1. The alignment of the 
anonymous struct's int1 member (explicitly 1 too) shouldn't 
even matter.


Why should it have an implicit alignment of 1? The alignment 
completely depends on the definition unless specified AFAIK.


Re: union.sizeof

2017-03-25 Thread kinke via Digitalmars-d-learn

On Saturday, 25 March 2017 at 22:45:22 UTC, ketmar wrote:

zabruk70 wrote:


//DMD 2.073.1 and latest 2.075.0-master-972eaed
//Windows 7 32-bit

union Union1
{
   align(1):
   byte[5] bytes5;
   struct
   {
 align(1):
 char char1;
 uint int1;
   }
}

void main ()
{
   import std.stdio: writefln;
   writefln("Union1.sizeof=%d", Union1.sizeof);  //prints 8, 
not 5

}

I expect size of Union1 is 5 (5 bytes == char + uint == 5).
Is this my bug or DMD?


`align(1) union Union1` will do the trick.

what you did is members packing. but the union itself is padded 
to integer size too. i.e. internal `align` will set aligning 
for *members*, and external `align` will change padding of the 
whole thing.


The union should have an implicit alignment of 1 already though, 
right? It's defined as the maximum of all member alignments, and 
both the bytes5 array and the anonymous struct members have an 
explicit alignment of 1. The alignment of the anonymous struct's 
int1 member (explicitly 1 too) shouldn't even matter.


Re: union.sizeof

2017-03-25 Thread kinke via Digitalmars-d-learn

On Saturday, 25 March 2017 at 22:54:30 UTC, zabruk70 wrote:

But for clearness...
I was thinked, that align not changes SIZE, but changes 
LOCATION.

I was thinked, that "align(X) union Union1"
just force compiler to place Union1 on boundaries of X bytes...


In order for all Union1 instances in an array to be aligned on 
boundaries of X bytes, the size of Union1 needs to be padded to a 
multiple of X in such a case.


Re: union.sizeof

2017-03-25 Thread zabruk70 via Digitalmars-d-learn

Thank you ag0aep6g and ketmar!!

I will use additional outside align.
I want packing inside, you are right.
But i check result size with assert() and failed.

But for clearness...
I was thinked, that align not changes SIZE, but changes LOCATION.
I was thinked, that "align(X) union Union1"
just force compiler to place Union1 on boundaries of X bytes...



Re: union.sizeof

2017-03-25 Thread ketmar via Digitalmars-d-learn

zabruk70 wrote:


//DMD 2.073.1 and latest 2.075.0-master-972eaed
//Windows 7 32-bit

union Union1
{
   align(1):
   byte[5] bytes5;
   struct
   {
 align(1):
 char char1;
 uint int1;
   }
}

void main ()
{
   import std.stdio: writefln;
   writefln("Union1.sizeof=%d", Union1.sizeof);  //prints 8, not 5
}

I expect size of Union1 is 5 (5 bytes == char + uint == 5).
Is this my bug or DMD?


`align(1) union Union1` will do the trick.

what you did is members packing. but the union itself is padded to integer 
size too. i.e. internal `align` will set aligning for *members*, and 
external `align` will change padding of the whole thing.


Re: union.sizeof

2017-03-25 Thread ag0aep6g via Digitalmars-d-learn

On 03/25/2017 11:37 PM, zabruk70 wrote:

union Union1
{
  align(1):
  byte[5] bytes5;
  struct
  {
align(1):
char char1;
uint int1;
  }
}

void main ()
{
  import std.stdio: writefln;
  writefln("Union1.sizeof=%d", Union1.sizeof);  //prints 8, not 5
}


I'm not sure how the align stuff is supposed to work exactly, but you 
get 5 when you add `align(1)` to the union itself, too:



align(1) union Union1
{
  align(1):
  byte[5] bytes5;
  struct
  {
char char1;
uint int1;
  }
}

pragma(msg, Union1.sizeof); /* "5LU" */