digitalmars.D.learn - void initialization vs alignment holes
- strtr (5/5) Mar 06 2010 This is probably going a bit above my head, but
- bearophile (14/17) Mar 06 2010 On Windows the sizeof of this struct is 16 bytes, so there is a big hole...
- strtr (7/31) Mar 06 2010 I should have thought of that, thanks ;)
- BCS (6/8) Mar 06 2010 IIRC zero filling a block is likely cheaper that zero filling holes in i...
- strtr (9/12) Mar 06 2010 And unless you will never compare the struct, as the garbage bits will a...
- bearophile (12/17) Mar 07 2010 If you need to fill the holes manually, then probably it's better to let...
- bearophile (4/4) Mar 07 2010 The situation is ugly, see the post in the main newsgroup:
- BCS (5/8) Mar 06 2010 real, char[n], byte[n] and short[m] (for n%4 != 0 and m%2 != 0) might be...
- strtr (2/10) Mar 06 2010 Sounds logical, thanks!
- BCS (4/16) Mar 06 2010 I don't actually *know* those will be a problem, but...
- bearophile (30/34) Mar 07 2010 You can use something like this :-)
This is probably going a bit above my head, but "the existence of alignment holes in the objects is accounted for, usually by setting them all to 0 upon initialization" I suspect this isn't the case for void initialization; if my struct has some alignment hole I better not void initialize it if ever I want to compare it with somthing. Is this correct? Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?
Mar 06 2010
strtr:I suspect this isn't the case for void initialization; if my struct has some alignment hole I better not void initialize it if ever I want to compare it with somthing. Is this correct?That has to be correct.Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?On Windows the sizeof of this struct is 16 bytes, so there is a big hole in the middle: struct Foo { short s; double d; } This is 12 bytes long, it has a smaller hole, even if the data needs the same space, because doubles need a stronger alignment: struct Foo { short s; int[2] i; } Bye, bearophile
Mar 06 2010
bearophile Wrote:strtr:Might this be worth an explicit mention on digitalmars?I suspect this isn't the case for void initialization; if my struct has some alignment hole I better not void initialize it if ever I want to compare it with something. Is this correct?That has to be correct.I should have thought of that, thanks ;) Suppose I'd still would like to use void optimizations, how do you clear the holes manually? align(1) and add a dummy member initialized to 0 to fill? Or would this not be an optimization any more because the way dmd aligned it optimally for the registers (or something) ? Not that I'm touching void any more, just interested :)Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?On Windows the sizeof of this struct is 16 bytes, so there is a big hole in the middle: struct Foo { short s; double d; } This is 12 bytes long, it has a smaller hole, even if the data needs the same space, because doubles need a stronger alignment: struct Foo { short s; int[2] i; }
Mar 06 2010
Hello Strtr,Suppose I'd still would like to use void optimizations, how do you clear the holes manually?IIRC zero filling a block is likely cheaper that zero filling holes in it. I'd avoid "=void" unless you know you will be copying structs into the space (that will copy the holes as well). -- ... <IXOYE><
Mar 06 2010
BCS Wrote:IIRC zero filling a block is likely cheaper that zero filling holes in it. I'd avoid "=void" unless you know you will be copying structs into the space (that will copy the holes as well).And unless you will never compare the struct, as the garbage bits will also be compared. I was thinking about using void in the struct opCall, bad idea. Maybe add static if( S.sizeof == members.sizeof ) S s = void; else S s; :D
Mar 06 2010
strtr:Might this be worth an explicit mention on digitalmars?<Currently the documentation has some semantic holes that must be filled :-)Suppose I'd still would like to use void optimizations, how do you clear the holes manually?If you need to fill the holes manually, then probably it's better to let the compiler clear the whole struct automatically at the beginning. If you really want to clear the struct instance manually, I can see few ways to do it: - don't leave holes in the struct, use an align(1) - use a memset(&somestruct, o, sizeof(typeof(somestruct))); This is preferred because it's safe, short, and fast. - Add strategically placed dummy items inside the struct, in the same position and size of the holes it has, and then assign them to zero normally. Holes do change in size for different operating systems (think about the type real, that has a different length across different operating systems, 10, 12 and 16 bytes), so this seems a bit too much complex way to solve the problem.Not that I'm touching void any more, just interested :)Sometimes void structs are useful, in performance critical spots of the program. But I suggest you to avoid it when possible. You have to be careful, because they can contain spurious pointers, that the conservative GC will use to keep objects alive. This happens especially if the struct contains pointers in the first place.I suspect this isn't the case for void initialization; if my struct has some alignment hole I better not void initialize it if ever I want to compare it with somthing.< And unless you will never compare the struct, as the garbage bits will also be compared.<I don't know. A well implemented opEquals and opCmp among structs has to ignore the contents of the holes. I have to do experiments *and* to go look at Phobos source code. In any case the D documentation must explain 100% about how such things work, the compiler writer must not be free to choose here. Bye, bearophile
Mar 07 2010
The situation is ugly, see the post in the main newsgroup: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=107153 Bye, bearophile
Mar 07 2010
Hello Strtr,Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?real, char[n], byte[n] and short[m] (for n%4 != 0 and m%2 != 0) might be an issue.-- ... <IXOYE><
Mar 06 2010
BCS Wrote:Hello Strtr,Sounds logical, thanks!Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?real, char[n], byte[n] and short[m] (for n%4 != 0 and m%2 != 0) might be an issue.
Mar 06 2010
Hello Strtr,BCS Wrote:I don't actually *know* those will be a problem, but... -- ... <IXOYE><Hello Strtr,Sounds logical, thanks!Would you ever have an alignment hole if all the struct contains are basic types(excluding bool)?real, char[n], byte[n] and short[m] (for n%4 != 0 and m%2 != 0) might be an issue.
Mar 06 2010
strtr:static if( S.sizeof == members.sizeof ) S s = void; else S s;You can use something like this :-) import std.stdio: writeln; int unusedBytesStruct(S)() if (is(S == struct)) { int totUsed; foreach (field; S.init.tupleof) totUsed += field.sizeof; return cast(int)S.sizeof - totUsed; } struct S1 { byte s; double d; } align(1) struct S2 { byte s; double d; } struct T { double d; int x; short s; ubyte u1, u2; } void main() { writeln(unusedBytesStruct!S1); // 7 writeln(unusedBytesStruct!S2); // 0 writeln(unusedBytesStruct!T); // 0 } Bye, bearophile
Mar 07 2010