January 23, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Todor Totev | Todor Totev wrote:
>> Walter Bright wrote:
>>> Try using enums instead of const variables, they don't take up any space in the object file.
>>
>> Thanks, but that makes only a dent in the overhead.
>
>
> Actually using enums instead of consts have a very nice side effect.
> Consider this declaration from win32:
>
> HANDLE CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
>
> Now, which invocation is correct?
>
> CreateFile("a", OPEN_EXISTING, FILE_SHARE_READ, null, GENERIC_READ ...)
> or
> CreateFile("a", OPEN_EXISTING, GENERIC_READ, null, FILE_SHARE_READ ...)
> or even
> CreateFile("a", GENERIC_READ, OPEN_EXISTING, null, FILE_SHARE_READ ...)?
>
> The compiler happily accepts all of them.
>
> Using enums, we have:
>
> enum FILE_SHARE {
> READ = 1,
> WRITE = 2,
> BOTH = READ | WRITE
> }
>
> enum DISPOSITION {
> CREATE_ALWAYS = 1,
> OPEN_EXISTING = 2
> }
>
> void CreateFile(char[] fileName, DISPOSITION disposition, FILE_SHARE share) {}
>
> int main() {
> // compiler allows unknown flags
> CreateFile("filename", cast(DISPOSITION)4, FILE_SHARE.READ);
>
> // when we swap the arguments by mistake
> CreateFile("filename", FILE_SHARE.READ, DISPOSITION.CREATE_ALWAYS);
>
> return 0;
> }
>
> This way if I make an error the compiler will very helpfully tell me
> what exactly is happening. Consider: CreateFont has 14 parameters,
> if the IDE does not help me i'd make an error when I use it, trust me
>
> On the other hand, when a new version of Windows come with expanded options
> I can just use the new numbers without breaking anything while the d package is
> updated.
>
> The dotnet framework uses enums and I really like the idea.
I agree that this is a great feature of D. And if you're willing to adapt the Win32 headers to use this convention then I would gladly accept them :-)
Sean
|
January 23, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | > Certainly, and I think you'll find many who agree, along with some who can't bear to type a few extra characters :) Yep > But that's a different type of issue than the one we're facing. I wish you had a fix for that one :p > No, nada, nein, не, όχι :-( |
January 23, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> As you can see, simply putting the Win32 object files into a library prior to linking reduced the application size by 51,100 bytes, but separate compilation had the same (bad) result as compiling all modules on one line.
I suggest linking with /MAP, which will generate a .map file listing all the modules linked in, and all the global symbols linked in. It's a lot easier to see what's happening with that than guessing based on the file size.
|
January 23, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Sean Kelly wrote:
>
>> As you can see, simply putting the Win32 object files into a library prior to linking reduced the application size by 51,100 bytes, but separate compilation had the same (bad) result as compiling all modules on one line.
>
>
> I suggest linking with /MAP, which will generate a .map file listing all the modules linked in, and all the global symbols linked in. It's a lot easier to see what's happening with that than guessing based on the file size.
Done that, Walter.
The difference is entirey Win32 struct inits, consts and so on. Remove the int consts, and you still have the struct inits ... almost enough to hand out at Christmas :)
What shall we do next?
|
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Sean Kelly wrote: >> As you can see, simply putting the Win32 object files into a library prior to linking reduced the application size by 51,100 bytes, but separate compilation had the same (bad) result as compiling all modules on one line. > > I suggest linking with /MAP, which will generate a .map file listing all the modules linked in, and all the global symbols linked in. It's a lot easier to see what's happening with that than guessing based on the file size. hello_small.map: Start Length Name Class 0002:00000000 00011570H _TEXT CODE 32-bit 0002:00011570 00000198H ICODE ICODE 32-bit 0003:00000000 00000004H .CRT$XIA DATA 32-bit 0003:00000010 00000004H .CRT$XIZ DATA 32-bit 0003:00000020 00000004H .CRT$XCA DATA 32-bit 0003:00000030 00000004H .CRT$XCZ DATA 32-bit 0003:00000040 00000004H .CRT$XPA DATA 32-bit 0003:00000050 00000004H .CRT$XPZ DATA 32-bit 0003:00000060 00000004H .CRT$XTA DATA 32-bit 0003:00000070 00000004H .CRT$XTZ DATA 32-bit 0003:00000074 00000000H IMP__DATA IMP__DATA 32-bit 0003:00000080 00005100H _DATA DATA 32-bit 0003:00005180 00000000H FMB DATA 32-bit 0003:00005180 00000024H FM DATA 32-bit 0003:000051A4 00000000H FME DATA 32-bit 0003:000051A4 00000000H XIB DATA 32-bit 0003:000051A4 0000001CH XI DATA 32-bit 0003:000051C0 00000000H XIE DATA 32-bit 0003:000051C0 00000000H XCB DATA 32-bit 0003:000051C0 00000014H XC DATA 32-bit 0003:000051D4 00000000H XCE DATA 32-bit 0003:000051D4 00000000H XIFCB DATA 32-bit 0003:000051D4 00000004H XIFU DATA 32-bit 0003:000051D8 00000000H XIFL DATA 32-bit 0003:000051D8 00000004H XIFM DATA 32-bit 0003:000051DC 00000000H XIFCE DATA 32-bit 0003:000051E0 00000000H CONST CONST 32-bit 0003:000051E0 00000000H EEND ENDBSS 32-bit 0003:000051E0 000016ECH _BSS BSS 32-bit 0003:000068CC 00000000H XOB BSS 32-bit 0003:000068CC 00000004H XO BSS 32-bit 0003:000068D0 00000000H XOE BSS 32-bit 0003:000068D0 00000000H XOFB BSS 32-bit 0003:000068D0 00000108H XOF BSS 32-bit 0003:000069D8 00000000H XOFE BSS 32-bit 0003:000069E0 00000419H c_common BSS 32-bit 0003:00006E00 00000000H STACK STACK 32-bit Program entry point at 0000A2AC -------------------------------------------------------------------------------- hello_large.map: Start Length Name Class 0002:00000000 00011570H _TEXT CODE 32-bit 0002:00011570 00000198H ICODE ICODE 32-bit 0003:00000000 00000004H .CRT$XIA DATA 32-bit 0003:00000010 00000004H .CRT$XIZ DATA 32-bit 0003:00000020 00000004H .CRT$XCA DATA 32-bit 0003:00000030 00000004H .CRT$XCZ DATA 32-bit 0003:00000040 00000004H .CRT$XPA DATA 32-bit 0003:00000050 00000004H .CRT$XPZ DATA 32-bit 0003:00000060 00000004H .CRT$XTA DATA 32-bit 0003:00000070 00000004H .CRT$XTZ DATA 32-bit 0003:00000074 00000000H IMP__DATA IMP__DATA 32-bit 0003:00000080 00011660H _DATA DATA 32-bit 0003:000116E0 00000000H FMB DATA 32-bit 0003:000116E0 00000024H FM DATA 32-bit 0003:00011704 00000000H FME DATA 32-bit 0003:00011704 00000000H XIB DATA 32-bit 0003:00011704 0000001CH XI DATA 32-bit 0003:00011720 00000000H XIE DATA 32-bit 0003:00011720 00000000H XCB DATA 32-bit 0003:00011720 00000014H XC DATA 32-bit 0003:00011734 00000000H XCE DATA 32-bit 0003:00011734 00000000H XIFCB DATA 32-bit 0003:00011734 00000004H XIFU DATA 32-bit 0003:00011738 00000000H XIFL DATA 32-bit 0003:00011738 00000004H XIFM DATA 32-bit 0003:0001173C 00000000H XIFCE DATA 32-bit 0003:00011740 00000000H CONST CONST 32-bit 0003:00011740 00000000H EEND ENDBSS 32-bit 0003:00011740 0000499CH _BSS BSS 32-bit 0003:000160DC 00000000H XOB BSS 32-bit 0003:000160DC 00000004H XO BSS 32-bit 0003:000160E0 00000000H XOE BSS 32-bit 0003:000160E0 00000000H XOFB BSS 32-bit 0003:000160E0 00000108H XOF BSS 32-bit 0003:000161E8 00000000H XOFE BSS 32-bit 0003:000161F0 00000419H c_common BSS 32-bit 0003:00016610 00000000H STACK STACK 32-bit Program entry point at 0000A2AC |
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
>> I suggest linking with /MAP, which will generate a .map file listing all the modules linked in, and all the global symbols linked in. It's a lot easier to see what's happening with that than guessing based on the file size.
>
> hello_small.map:
Please be sure you are linking with the /MAP switch, as it will give all the symbols, not just the segments.
|
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Sean Kelly wrote: >>> I suggest linking with /MAP, which will generate a .map file listing all the modules linked in, and all the global symbols linked in. It's a lot easier to see what's happening with that than guessing based on the file size. >> >> hello_small.map: > > Please be sure you are linking with the /MAP switch, as it will give all the symbols, not just the segments. Oops, I missed the leading slash. The output is obviously quite large so I'm just going to note some of the larger blocks that are present in hello_large.map that are missing from hello_small.map: 0003:0001172C _D5tango3sys5win325Types10ACE_HEADER6__initZ 0042372C ... 0003:00002C08 _D5tango3sys5win325Types9cSTARTDOCi 00414C08 0003:00001074 _D5tango3sys5win325Types10RASCS_DONEi 00413074 ... 0003:00014604 _D5tango3sys5win325Types10WINDOWINFO6__initZ 00426604 The first block goes from line 410 to line 6719 in the map file, and the second block goes from line 8047 to line 14559 in the map file. All told, that's 12821 separate constants or initializers in the manually linked version that seem absent from the library-based version. |
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> The first block goes from line 410 to line 6719 in the map file, and the second block goes from line 8047 to line 14559 in the map file. All told, that's 12821 separate constants or initializers in the manually linked version that seem absent from the library-based version.
That means that, in the library based version, nothing in the explicitly linked .obj files referenced them.
If you want to find out what reference is pulling in a particular library module, use lib to remove that library module, relink, and note the undefined reference.
|
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Sean Kelly wrote: >> The first block goes from line 410 to line 6719 in the map file, and the second block goes from line 8047 to line 14559 in the map file. All told, that's 12821 separate constants or initializers in the manually linked version that seem absent from the library-based version. > > That means that, in the library based version, nothing in the explicitly linked .obj files referenced them. If that's true then nothing in either version referenced them. The application is identical in both cases but for some of the objects living in a library in the small case. > If you want to find out what reference is pulling in a particular library module, use lib to remove that library module, relink, and note the undefined reference. See above. Sean |
January 24, 2007 Re: Big problem with Small programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Todor Totev wrote:
>>> Walter Bright wrote:
>>>> Try using enums instead of const variables, they don't take up any space in the object file.
>>>
>>> Thanks, but that makes only a dent in the overhead.
>>
>>
>> Actually using enums instead of consts have a very nice side effect.
>> Consider this declaration from win32:
>>
>> HANDLE CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
>>
>> Now, which invocation is correct?
>>
>> CreateFile("a", OPEN_EXISTING, FILE_SHARE_READ, null, GENERIC_READ ...)
>> or
>> CreateFile("a", OPEN_EXISTING, GENERIC_READ, null, FILE_SHARE_READ ...)
>> or even
>> CreateFile("a", GENERIC_READ, OPEN_EXISTING, null, FILE_SHARE_READ ...)?
>>
>> The compiler happily accepts all of them.
>>
>> Using enums, we have:
>>
>> enum FILE_SHARE {
>> READ = 1,
>> WRITE = 2,
>> BOTH = READ | WRITE
>> }
>>
>> enum DISPOSITION {
>> CREATE_ALWAYS = 1,
>> OPEN_EXISTING = 2
>> }
>>
>> void CreateFile(char[] fileName, DISPOSITION disposition, FILE_SHARE share) {}
>>
>> int main() {
>> // compiler allows unknown flags
>> CreateFile("filename", cast(DISPOSITION)4, FILE_SHARE.READ);
>>
>> // when we swap the arguments by mistake
>> CreateFile("filename", FILE_SHARE.READ, DISPOSITION.CREATE_ALWAYS);
>>
>> return 0;
>> }
>>
>> This way if I make an error the compiler will very helpfully tell me
>> what exactly is happening. Consider: CreateFont has 14 parameters,
>> if the IDE does not help me i'd make an error when I use it, trust me
>>
>> On the other hand, when a new version of Windows come with expanded options
>> I can just use the new numbers without breaking anything while the d package is
>> updated.
>>
>> The dotnet framework uses enums and I really like the idea.
>
> I agree that this is a great feature of D. And if you're willing to adapt the Win32 headers to use this convention then I would gladly accept them :-)
>
>
> Sean
As far as possible, we did that, for the ones that actually are enums. The problem is, most of those things aren't actually enums! They are complicated bitfields that get ORed together.
|
Copyright © 1999-2021 by the D Language Foundation