www.digitalmars.com         C & C++   DMDScript  

c++.dos.32-bits - DOSX big EXE with static array

reply Heinz Saathoff <hsaat bre.ipnet.de> writes:
Hello,

why do static arrays (or every variable defined as static) generate big 
EXE files when compiled in DOSX. This example

#include <stdio.h>

static
char adr[1000000];

int main()
{  printf("&adr[10] = %p\n", adr+10);
   return 0;
}


generates a EXE-file of more than 1MB when compiled with 

   sc -mx test.c

Without static the resulting EXE is only 30k in size.
BTW, the same file (with static) compiled as Win32 console isn't growing 
with static.

I thought that uninitialized static variables could go to an extra 
segment that is allocated and cleared by the startup code.

Regards,
	Heinz
Sep 09 2001
parent reply "Walter" <walter digitalmars.com> writes:
It looks like a bug in the linker. I suggest using malloc() for large arrays
as a workaround. -Walter

Heinz Saathoff wrote in message ...
Hello,

why do static arrays (or every variable defined as static) generate big
EXE files when compiled in DOSX. This example

#include <stdio.h>

static
char adr[1000000];

int main()
{  printf("&adr[10] = %p\n", adr+10);
   return 0;
}


generates a EXE-file of more than 1MB when compiled with

   sc -mx test.c

Without static the resulting EXE is only 30k in size.
BTW, the same file (with static) compiled as Win32 console isn't growing
with static.

I thought that uninitialized static variables could go to an extra
segment that is allocated and cleared by the startup code.

Regards,
 Heinz

Sep 10 2001
parent reply Heinz Saathoff <hsaat bre.ipnet.de> writes:
Walter schrieb...
 It looks like a bug in the linker. I suggest using malloc() for large arrays
 as a workaround. -Walter

Already used this as a workaround. But I was astonished when I saw the difference in size between a win-console mode program and a DOSX program here. Thanks, Heinz
Sep 10 2001
parent reply Laurentiu Pancescu <plaur crosswinds.net> writes:
No linker bug WRT this behavior... the reason consists in the
way Windows loads executables: the PE must have, of course, a
complete DATA section (initialized data), while for the BSS
section (uninitialized data, as that array), only the total size
must be known, and is allocated automatically by Windows when the
program is loaded.

DOS doesn't do this (well, it actually depends on the DOS
extender and the compiler and linker).

There was a question on DM's web site about WDOSX being able to
run DMC programs (probably Win32 console programs)... it
can't!  It misses some functions from Win32 API emulation. 
Actually, it can't run even Borland C++ 5.5.1 programs (it could only
run only C programs, not C++).  Perhaps someone should update
this on DM site: it's better than "I don't know"...  :)


Regards,
  Laurentiu

Walter schrieb...
 It looks like a bug in the linker. I suggest using malloc() for large arrays
 as a workaround. -Walter

Already used this as a workaround. But I was astonished when I saw the difference in size between a win-console mode program and a DOSX program here. Thanks, Heinz

Sep 10 2001
parent reply Heinz Saathoff <hsaat bre.ipnet.de> writes:
Laurentiu Pancescu schrieb...
 No linker bug WRT this behavior... the reason consists in the
 way Windows loads executables: the PE must have, of course, a
 complete DATA section (initialized data), while for the BSS
 section (uninitialized data, as that array), only the total size
 must be known, and is allocated automatically by Windows when the
 program is loaded.
 
 DOS doesn't do this (well, it actually depends on the DOS
 extender and the compiler and linker).

This doesn't explain why the EXE gets big when static is used and small when not. In both cases the array is an uninitialized memory region that could go to the BSS. The only difference (for the linker) is that the static defined array is not visible to other compilation units (internal linkage). Disassembling shows that the non static array generates a comm (COMDAT?) symbol to the linker where the static defined array goes into BSS. Questions to Walter: 1) Do comdats always generate linkable symbols? If not it should be possible to place static objects into comdat 2) The space for the public arrays in comdat must also be allocated and cleared during startup. Where's the difference to BSS? I would agree to Walter that the problem is in the linker that for some reasons treat the uninitialized BSS linke the initialized DATA segment in DOSX. Regards, Heinz
Sep 10 2001
parent "Walter" <walter digitalmars.com> writes:
Heinz Saathoff wrote in message ...
Disassembling shows that the non static array generates a comm (COMDAT?)
symbol to the linker where the static defined array goes into BSS.
Questions to Walter:
1) Do comdats always generate linkable symbols? If not it should
   be possible to place static objects into comdat

Yes.
2) The space for the public arrays in comdat must also be allocated
   and cleared during startup. Where's the difference to BSS?

Uninitialized data goes into BSS, which gets cleared by the startup code. BSS getting explicitly allocated may just be an artifact of how the dos extender was done. I don't know. All the BSS thing is anyway is a way to reduce the size of the executable file, it doesn't reduce the size of it in memory at all.
Sep 11 2001