Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
May 14, 2004 Why large binary sizes with struct declaration? - why.d | ||||
---|---|---|---|---|
| ||||
Attachments: | Hi everyone, I'm wondering, why does code like this: ____why.d_____________________________________ struct exampleObj { uint[1024*32] mydata; } int main() { return 0; } ____end of file_______________________________ produce an object file that is 129.6 KB?? As far as I understand, the exampleObj should only be a compile-time definition, and not an object built into the binary because I never declare an instance of it. (If I comment out the struct exampleObj declaration, the .o file goes down to 1.5KB. ) My question is, why does this make a difference? |
May 14, 2004 Re: Why large binary sizes with struct declaration? - why.d | ||||
---|---|---|---|---|
| ||||
Posted in reply to Braden MacDonald | Remember how D allows you to specify initial values for fields in structs? Apparently this is done by using a memcpy from an example object, in new. This should be more compact and probably faster than the alternative - a procedural constructor definition. Except in your case, where the object could be built with a loop instead of thousands of assignments. (I am interpreting gdc assembler output. I've found it interesting to compare assembler: compile twice with a small change and use a graphical diff util.) The object you define is not "static" so the definition could be used by another module. However, I tried making it "static struct {" and that did not have an effect. Kevin In article <c81h4p$1uk6$1@digitaldaemon.com>, Braden MacDonald says... > >Hi everyone, > I'm wondering, why does code like this: >____why.d_____________________________________ > >struct exampleObj { >uint[1024*32] mydata; >} > >int main() { > return 0; >} > >____end of >file_______________________________ > >produce an object file that is 129.6 KB?? >As far as I understand, the exampleObj should only be a compile-time >definition, and not an object built into the binary because I never declare an >instance of it. (If I comment out the struct exampleObj declaration, the .o >file goes down to 1.5KB. ) > >My question is, why does this make a difference? > > >begin 0644 why.d >M+RH@=VAY+F0*("`@,C(Q+C@@2T(@8V]M<&EL960@)B!L:6YK960*("`@,3(Y >M+C8@2T(@8V]M<&EL960@*"YO(&9I;&4@;VYL>2D*"B`@("YO8FH@9FEL92!I >M<R`G;VYL>2<@,2XU2T(@:68@=&AE('-T<G5C="!D969I;FET:6]N(&ES(&-O >M;6UE;G1E9"!O=70N"BHO"@H*<W1R=6-T(&5X86UP;&5/8FH@>PH)=6EN=%LQ >M,#(T*C,R72!M>61A=&$["GT*+R\@22!D;VXG="!D96-L87)E(&%N>2!I;G-T >M86YC97,@;V8@86X@97AA;7!L94]B:B!O8FIE8W0N"@II;G0@;6%I;B@I('L* >-"7)E='5R;B`P.PI]"GAA >` >end |
May 14, 2004 Re: Why large binary sizes with struct declaration? - why.d | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kevin Bealer | Yes, but in my mind, it is only a definition at compile time. The only time I want to use this definition would be from another file, via "import why". ___ How I think of it ______ int; int main() { return 0; } ____________________________ In that code, all I'm saying is that there is such a thing as int, merely for compiler verification of any code referencing it. I am not declaring an int, because I never give it a name. Same thing with the struct. So why does it get into the binary? The way I use it is something like this: ____helper.d________________ struct Elephant { uint[1024*32] toes; int count() { int count; for (int i=0;i<toes.length;i++) { if (toes[i] != 0) { count++; } } return count; } } ______main.d________________ import helper; int main { Elephant e1; ei.toes[7] = 1454325; printf("The elephant has %d big toes.", e1.count()); return 0; } ____________________________ So why does the helper.d object file contain binary space for the Elephant object? Sorry if code is wrong or explanation hard to understand; it's morning here and I'm in a hurry. Thanks. |
May 14, 2004 Re: Why large binary sizes with struct declaration? - why.d | ||||
---|---|---|---|---|
| ||||
Posted in reply to Braden MacDonald | In article <c82mba$i2i$1@digitaldaemon.com>, Braden MacDonald says... > >Yes, but in my mind, it is only a definition at compile time. The only time I want to use this definition would be from another file, via "import why". I think what you are seeing is not an object of this type, but rather static data that is essentially part of the constructor definition and thus created in the module where you define the class. For an object that is 128 bytes and has a lot of entropy in the initialization values, this technique is probably very beneficial. Imagine the (generated) constructor definition to look like this: /+ Note: this is a guess by me, haven't looked at the compiler code. +/ why::exampleObj::this { byte * boilerplate = "\0\0\0\0\0....\0"; // 128 KB memcpy(this, boilerplate, 128*1024*1024); /+ your constructor would be inlined here +/ } The same thing happens in the following code: --- int foo(double x) { return x += strlen("alphabet soup"); } int main(char[][] argv) { return argv.size(); } --- The string literal is never used, and the function is never called; but the binary will probably still contain both. Because foo() is emitted, the string literal has to be. Global analysis could possibly remove these unused parts. It would have to be done at link time, right? Otherwise another module might call the constructor. Kevin |
May 15, 2004 Re: Why large binary sizes with struct declaration? - why.d | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kevin Bealer | Ah, I see now. That helps a lot - thanks. In article <c82odg$l0i$1@digitaldaemon.com>, Kevin Bealer says... >I think what you are seeing is not an object of this type, but rather static >data that is essentially part of the constructor definition and thus created in >the module where you define the class. For an object that is 128 bytes and has >a lot of entropy in the initialization values, this technique is probably very >beneficial. > >Imagine the (generated) constructor definition to look like this: > >/+ Note: this is a guess by me, haven't looked at the compiler code. +/ > >why::exampleObj::this { byte * boilerplate = "\0\0\0\0\0....\0"; // 128 KB memcpy(this, boilerplate, 128*1024*1024); > >/+ your constructor would be inlined here +/ } |
Copyright © 1999-2021 by the D Language Foundation