The First Traditional "Hello world!"

From MorphOS Library

Revision as of 15:58, 23 October 2010 by Krashan (talk | contribs)

Grzegorz Kraszewski


"Hello World!" With the Standard C Library

With the standard C library, one can use the "Hello World!" example exactly as found in a C handbook. It is given below, just for completness:


#include <stdio.h>

int main(void)
{
  printf("Hello World!\n");
  return 0;
}


This source may be copied to a text editor and saved as helloworld.c. To compile it, one opens a shell window (from Ambient menu, or using rcommand + n key combo) and changes current directory to the one, where C source is located. The compiler is ran as follows:


gcc -o helloworld helloworld.c


The compiler produces helloworld executable, which has 10 340 bytes on my system. Note that MorphOS pays little attention to filename extensions, so ending the executable name with .exe is not needed, however possible. Traditionally MorphOS executables are named without any extensions. The −o compiler option specifies desired executable name. If this option is not given, the executable will be named a.out (for some historical reasons).


As stated in the SDK section, the standard C library will be delivered by ixemul.library. It can be easily confirmed by tracing disk activity of helloworld using Snoopium tool.

Snoopium ixemul.png

It can be also seen that many other libraries are also opened including ones related to TCP/IP networking. It looks like overkill for such a small program. This happens, because ixemul.library creates a complete unixlike environment for the application, which is not needed in this simple case. That is why libnix alternative is recommended for the standard library. To use it, a −noixemul option has to be added, so the compiler is called as follows:


gcc -noixemul -o helloworld helloworld.c


The generated executable is much larger (30 964 bytes here), which just confirms the fact, that libnix, which is now in use, is a statically linked library. Size of functions used adds to the size of executable. Every C handbook states, that printf() is the most expensive function of standard I/O, which has been just proven experimentally... On the other hand program activity, as traced with Snoopium, reduces to three entries. No external resources are opened.


"Hello World!" With MorphOS Native API

MorphOS API (Application Programmer Interface) provides complete file and console input/output. In fact, functions in C and C++ standard libraries are more or less complex wrappers around MorphOS native calls. Using the native API has following advantages:

  • Programs are much shorter.
  • Programs are faster, thanks to stripping some layers of abstraction.
  • Programs are less resource hungry.
  • Native API gives full access to MorphOS specific features.


These advantages come at a price:

  • Programs using native API are not portable (except of porting to AmigaOS and AROS to some degree).
  • Native printf()-like functions do not support floating point numbers.


The "Hello World!" example using native API looks as follows:


#include <proto/dos.h>

int main(void)
{
  Printf("Hello World!\n");
  return 0;
}


The included header includes all things needed to use the dos.library, where Printf() function is located. The function itself works the same as standard printf(), with some minor differencies. The code is being compiled with command:


gcc -noixemul -o helloworld helloworld.c


The command is the same as for program using libnix and printf(), just standard C function is not used, so it is not linked. Then, the executable size reduces to 13 500 bytes.


Why libnix is still needed in spite of standard library calls are not used? Can't one just compile with −nostdlib? Except of C library, libnix provides application startup code. A program without the startup code can work launched from shell, but will crash when started from Ambient. The startup code has also automatic MorphOS libraries opening and closing feature. Then rejecting libnix completely is possible, but requires writing a custom startup code and handling libraries opening and closing manually.


Note: rejecting libnix is usually done for MorphOS components not being applications, like shared libraries or Reggae and MUI public classes. It can be also done for ordinary programs just to make them shorter, especially if a program is small. For bigger projects bytes gained by writing custom startup are not worth the effort usually.