home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / languages / northc_384 / mini-hello / readme < prev    next >
Text File  |  1990-08-30  |  6KB  |  133 lines

  1.   (c) 1990 S.Hawtin.
  2.   Permission is granted to copy this file provided
  3.    1) It is not used for commercial gain
  4.    2) This notice is included in all copies
  5.    3) Altered copies are marked as such
  6.  
  7.   One complaint that is voiced about 'C' is that trivial programs are too 
  8. large.  This opinion is usually held by those who have "played with" 'C' 
  9. and only every produced trivial programs, in this directory I explain how 
  10. to make smaller 'C' programs, and what you lose by doing so.
  11.  
  12.   Before I can describe how to create small programs I must explain why 
  13. the simplest 'C' program, which is
  14.  
  15.     main()
  16.        {
  17.         }
  18.  
  19. takes so much space.
  20.  
  21.   The first thing to note is that every 'C' program consists of three 
  22. parts, the startup code, the programmers routines, and the 'C' library.  
  23. The startup code is a standard set of routines that are called when every 
  24. 'C' program starts, these routines set up things so that the 'C' library 
  25. will work and calls the users main() routine in a standard way.  The 'C' 
  26. library is a set of routines that the user may want to call, these range 
  27. from the very well used routines such as printf() to the extremely obscure 
  28. routines such as strpbrk().
  29.  
  30.   The 'C' library will only add code if one of the other two parts 
  31. requires it, so for example the strstr() function is added to the 
  32. application only if it is called from the startup, which it isn't, or the 
  33. users code.  For some routines the situation is more complicated, the 
  34. fputs() routine, for example, calls the fputc() routine, so if the startup 
  35. calls fputs() then both fputs() and fputc() are linked into the final 
  36. executable program from the 'C' library.
  37.  
  38.   The normal 'C' startup code calls some routines in the 'C' library, on 
  39. real applications this makes little difference to the size of the final 
  40. code, because the users code probably calls all the routines that the 
  41. startup uses anyway.  On trivial applications the chances are that the 
  42. routines the application calls are different from those that the startup 
  43. uses.  For example the startup uses fputs() if the application calls 
  44. printf() then the final code must include both routines, even though they 
  45. do almost the same job, so the final program will be larger.  So if the 
  46. hello world program is written as
  47.  
  48.     #include <stdio.h>
  49.  
  50.     main()
  51.        {fputs("Hello world\a\n",stdout);
  52.         }
  53.  
  54. then the executable code will be smaller, the routines that the startup 
  55. uses are
  56.  
  57.     atexit()        CloseLibrary()        exit()
  58.     fclose()        fflush()           fputc()
  59.     fputs()        free()            ltoa()
  60.     malloc()        OpenLibrary()        strncpy()
  61.     _exit()        _main()
  62.  
  63. so if you stick to this set you will reduce the size of your program.
  64.  
  65.   This is all to the good, however since the empty program is a few 
  66. kilobytes long this is not the ultimate answer, we must reduce the size of 
  67. the startup code.
  68.  
  69.   The startup code is the same for the vast majority of 'C' programs, the 
  70. programmer has to work hard to use a different startup routine.  This 
  71. means that the startup must initialise the data structures for all the 
  72. possible library routines that the program can call, for example the 
  73. malloc() family of routines maintain a list of allocated memory chunks, so 
  74. that they can be freed when the program exits, this list must be 
  75. initialised just in case the program is going to call malloc().  There are 
  76. quite a few lists and data structures that must be set up.
  77.  
  78.   The startup code is split over a number of routines, the "crt0.asm" file 
  79. contains most of the low level routines, these call the higher level 
  80. routines.  The low level routines initialise the malloc() lists, the 
  81. floating point support, the Amiga library support, the low level file 
  82. handling, starting from the Workbench and the low level _exit() routine.  
  83. The high level routines deal with the "FILE" structures, the exit() and 
  84. atexit() routines, and the command line processing.  Most of the space in 
  85. the high level routines deals with the command line processing, this is an 
  86. area that is often neglected, for example the command
  87.  
  88.     example "Arg one in quotes" two three
  89.  
  90. has three arguments.  Other languages, and even some 'C' compilers, will 
  91. treat this as six arguments.
  92.  
  93.   So the reason why the empty program is so large is that it contains 
  94. support for all the obscure 'C' routines you could have used, even if you 
  95. don't.  So the ultimate way to reduce the final size of your 'C' code is 
  96. to take out the support for the routines you are not going to use, start 
  97. with the "crt0.asm" file, and take out the calls that initialise the 
  98. structures you don't want.  This is what I have done in this directory, I 
  99. have created "crt1.asm" a startup that sets up very little, and calls the 
  100. routine _main().
  101.  
  102.   Of course if you want to use this trick to reduce the size of a program 
  103. you would take the following steps,
  104.  
  105.     1)  Get the program working with the normal startup.
  106.     2)  Change the main() routine from
  107.  
  108.             main(argc,argv)
  109.                 int argc;
  110.                 char **argv;
  111.                {
  112.                 .
  113.                 .
  114.                 }
  115.  
  116.         remove all the FILE references and change the function to
  117.  
  118.             extern long _cmndlen;
  119.             extern char *_cmndstr;
  120.             extern long _fromWB;
  121.  
  122.             _main()
  123.                {
  124.                 .
  125.                 .
  126.                 }
  127.  
  128.     3)  Get a local copy of "crt1.asm" and remove the bits you don't need.
  129.  
  130.     4)  Edit your Makefile to use the local "crt1.o" rather than "clibs:crt0.o".
  131.  
  132. Once you have done all this you will learn a great deal about the guru, it 
  133. really is simpler to live with the larger programs.