www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Are padding bits always zero?

reply Honey <honey pot.com> writes:
Hi everyone!

Are there any guarantees about the values of padding bits in 
structs?

Thanks,
Honey
Jun 24
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/24/17 4:44 AM, Honey wrote:
 Hi everyone!
 
 Are there any guarantees about the values of padding bits in structs?
 
 Thanks,
 Honey
Any padding bits between fields should be 0 as long as the struct is initialized (i.e. as long as you don't do Struct s = void). Padding bits after the fields I assume would be 0, but I don't know if this is defined. It's possible the compiler doesn't consider those bits to be part of the struct, and just there for alignment. There is no spec for this, but I know that when the compiler has to fill gaps with something it chooses 0. -Steve
Jun 24
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
wrote:
 There is no spec for this, but I know that when the compiler 
 has to fill gaps with something it chooses 0.
I'm almost certain there at least used to be a spec for this, because I remember citing a link to someone who then complained that this zero requirement hurt optimization of void members. On the other hand though, the zero padding requirement does simplify equality to being memcmp. I can't find the reference now. Perhaps I'm looking in the wrong place... or perhaps that optimization complaint actually got the requirement removed from the spec. I don't know. (I find search of most D stuff to be fruitless and heavily rely on my old brain memory to index these things, but while my memory is pretty good, it isn't flawless.)
Jun 24
next sibling parent Honey <honey pot.com> writes:
On Saturday, 24 June 2017 at 14:03:16 UTC, Adam D. Ruppe wrote:
 On the other hand though, the zero padding requirement does 
 simplify equality to being memcmp.
That's the reason for my question.
Jun 24
prev sibling parent Honey <honey pot.com> writes:
On Saturday, 24 June 2017 at 14:03:16 UTC, Adam D. Ruppe wrote:
 On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
 wrote:
 There is no spec for this, but I know that when the compiler 
 has to fill gaps with something it chooses 0.
I'm almost certain there at least used to be a spec for this, because I remember citing a link to someone who then complained that this zero requirement hurt optimization of void members. On the other hand though, the zero padding requirement does simplify equality to being memcmp.
The only hint I could find is this statement from Walter: http://forum.dlang.org/post/hn11oh$1usk$1 digitalmars.com
Jun 24
prev sibling parent reply Honey <honey pot.com> writes:
On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
wrote:
 Any padding bits between fields should be 0 as long as the 
 struct is initialized (i.e. as long as you don't do Struct s = 
 void).

 Padding bits after the fields I assume would be 0, but I don't 
 know if this is defined. It's possible the compiler doesn't 
 consider those bits to be part of the struct, and just there 
 for alignment.

 There is no spec for this, but I know that when the compiler 
 has to fill gaps with something it chooses 0.
Thanks. Your answer has generated more questions. ;-) Let's say, I have a struct S of size n with m bits of padding at the end. How can I find m? Is it possible to provide a facility Pad such that for any struct T, Pad!T is a struct that mimics T but contains explicit instead of implicit padding? E.g. struct Foo { ubyte b; double d; int i; } struct Pad!Foo { ubyte b; ubyte[7] __padding_0; double d; int i; ubyte[4] __padding_1; }
Jun 24
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/24/17 10:32 AM, Honey wrote:
 On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer wrote:
 Any padding bits between fields should be 0 as long as the struct is 
 initialized (i.e. as long as you don't do Struct s = void).

 Padding bits after the fields I assume would be 0, but I don't know if 
 this is defined. It's possible the compiler doesn't consider those 
 bits to be part of the struct, and just there for alignment.

 There is no spec for this, but I know that when the compiler has to 
 fill gaps with something it chooses 0.
Thanks. Your answer has generated more questions. ;-) Let's say, I have a struct S of size n with m bits of padding at the end. How can I find m? Is it possible to provide a facility Pad such that for any struct T, Pad!T is a struct that mimics T but contains explicit instead of implicit padding? E.g. struct Foo { ubyte b; double d; int i; } struct Pad!Foo { ubyte b; ubyte[7] __padding_0; double d; int i; ubyte[4] __padding_1; }
Of course it's possible. Best thing I can think of is using offsetof and sizeof: string generatePad(T)() { string result = ""; size_t lastIndex = 0; foreach(x; T.tupleof) { // not sure about offsetof working like this, you may need to do // tupleof with index auto padSpace = x.offsetof - lastIndex; if(padSpace > 0) result ~= "ubyte[" ~ padSpace ~ "] __padding__" ~ padIndex ~ ";"; result ~= typeof(x).stringof ~ " " ~ x.stringof ~ ";"; lastIndex = x.offsetof + x.sizeof; } return result; } This needs a bit of work, but you get the idea. I'm not sure all the properties work correctly there. Then you mixin the result of that function to get your members. Adding the ending padding would involve comparing lastIndex to the sizeof T. -Steve
Jun 24