home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: sparky!uunet!mcsun!news.funet.fi!hydra!klaava!wirzeniu
- From: wirzeniu@klaava.Helsinki.FI (Lars Wirzenius)
- Subject: Re: Followup on size of executables.
- Message-ID: <1993Jan4.122907.18756@klaava.Helsinki.FI>
- Organization: University of Helsinki
- References: <93004.051358RVK@psuvm.psu.edu>
- Date: Mon, 4 Jan 1993 12:29:07 GMT
- Lines: 106
-
- <RVK@psuvm.psu.edu> writes:
- [ assembly program is 548 bytes, the equivalent C program is 6762
- bytes ]
-
- >This brings us to another question: Who cares for a few K's
- >more or less?
-
- Plenty of people, including for myself, when there are hundreds of
- small programs, each using a few extra kilobytes. Wastes disk space,
- which is a scarce enough resource for me (gotta fit those c.l.c
- archives on the same disk :-), so 100 utilities using each 5 kB extra
- waste half a megabyte. Luckily, I don't quite have to suffer that
- much, see below.
-
- Then again, there are plenty of people who don't care, and with good
- reasons: _they_ have the disk space so they don't have to care about
- the size that much, and for most larger programs, an overhead of 5 kB
- is, well, like a galaxy in the universe.
-
- >why do I have to link with everything that's there in stdio.h to
- >produce an executable?
-
- You don't. A header is (or should be) just a lot of _declarations_,
- and declarations don't take up space in the compiled program, only in
- the compiler's symbol table (the part of the compiler that keeps track
- of all declared and defined variables, functions, etc).
-
- What happens is that when you use any of the standard I/O functions in
- your program, not only that function, but also a lot of supporting
- functions also get linked into the program. These functions include
- stuff for buffer management, conversion for text-mode files, etc.
- This can be a lot of stuff, and might take several kilobytes. On top
- of that, printf is usually one of the biggest functions of those
- declared in the stdio library, because it so much more complex than,
- for instance, puts.
-
- >This brings me to my final question: Is there no way other than
- >programming in assembly, to produce a really small executable?
- >I would like to use C, but I don't know how (if at all possible)
- >to do that.
-
- It depends on the operating system and C compiler. On _my_ machine, a
- 386 running Linux, using the same source code you used,
-
- >#include <stdio.h>
- >int main() { printf("Hello, World\n"); return 0;}
-
- I get an executable that is 9216 bytes. It is actually smaller, but
- it is padded to two full 4 kB pages (one for data, one for code) so
- that Linux can dynamically load any part of it while running the
- program without having to parse the file to find the thousand bytes or
- so it actually needs. (This means that the operating system will only
- load those parts of the program that are actually used when running
- it, and can re-load them if it has to discard them because it runs out
- of memory. The wonders of good operating systems.) The extra
- kilobyte is a header that contains information about the layout of
- various parts in the program file; it has to be a full disk block
- (1 kB) so that the 4 kB pages are aligned on disk block boundaries.
-
- Now, for small programs that run quickly, there is actually no need to
- be able to reload pages from the executable. If I link the program so
- that it uses an executable format that cannot be loaded, I can get rid
- of the 1 kB header and don't have to make the code and data segments
- occupy full 4 kB blocks. The result is an executable of 1228 bytes.
-
- Another useful feature of Linux is that it has shared libraries, which
- means that the library routines are not actually linked into the
- program, but are loaded only once for the whole system and all
- programs using the library share the same copy in memory of it. This
- reduced both the size of the disk file and the amount of memory it
- uses while running. (It is possible to link "statically", so that the
- shared library is not used; hello linked this way is 37888 bytes, or
- 31076 bytes if dynamic loading is disabled.)
-
- Yet another thing which helps is that none of the above executables
- contains symbol table information, which is useful mostly for
- debugging, nor any other information not necessary for running the
- program, such as support for source level debuggers.
-
- Dynamic linking (and disabling it) and shared libraries (or dynamic
- libraries, which are slightly different) are available on most modern
- versions of Unix, and, I assume, most other modern operating systems.
-
- Under DOS, with at least some versions of Borland's compilers, you can
- try similar tricks by using a non-standard startup module, the c0x.obj
- file that is linked before any of your own modules and which takes
- care of all the stuff that has to be done before calling main. Stuff
- like breaking the command line to an argv array, and initializing the
- standard I/O library.
-
- The source code for c0x.obj is provided, and you can try hacking it so
- that you can link the program without including any of the standard
- libraries, if you can write the program so that it doesn't need any
- functions thereof. This means that you have to write everything in
- terms of builtin functions, such as those for generating interrupts,
- and this can be a pain in the parts below your back, but it might be
- worth it if every byte counts. I believe there is an example of doing
- this somewhere in the files that come with the compiler.
-
- Note that trying to write a program with no support from the standard
- libraries (and that means _any_ support, not even string functions)
- will result in a program that is, um, somewhat unportable.
-
- --
- Lars.Wirzenius@helsinki.fi (finger wirzeniu@klaava.helsinki.fi)
- MS-DOS, you can't live with it, you can live without it.
-