Difference between revisions of "The First Traditional "Hello world!""

From MorphOS Library

m ("Hello World!" With the Standard C Library)
m ("Hello World!" With the MorphOS Native API: style)
 
(13 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
''Grzegorz Kraszewski''
 
''Grzegorz Kraszewski''
 +
----
 +
<small>This page in other languages: [[Pierwsze tradycyjne "Hello world!"|Polish]]</small>
  
  
 
=="Hello World!" With the Standard C Library==
 
=="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:
+
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 completeness:
  
  
Line 15: Line 17:
  
  
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:
+
This source may be copied to a text editor and saved as ''helloworld.c''. To compile it, one opens a shell window (from the Ambient menu, or using the ''rcommand + n'' key combo) and changes current directory to the one, where the C source is located. The compiler is run as follows:
 +
 
  
 
<tt>gcc -o helloworld helloworld.c</tt>
 
<tt>gcc -o helloworld helloworld.c</tt>
  
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 '''&minus;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 [[Installation_of_Software_Development_Kit_and_its_basic_usage#Standard_C_and_C++_Libraries|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.
+
The compiler produces a ''helloworld'' executable, which is 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, it can be done. Traditionally MorphOS executables are named without any extensions. The '''&minus;o''' compiler option specifies a desired executable name. If this option is not given, the executable will be named ''a.out'' (for some historical reasons).
 +
 
 +
 
 +
As stated in the [[Installation_of_Software_Development_Kit_and_its_basic_usage#Standard_C_and_C++_Libraries|SDK section]], the standard C library will be provided by ''ixemul.library''. It can be easily confirmed by tracing the disk activity of ''helloworld'' using the ''Snoopium'' tool.
 +
 
  
 
[[File:snoopium_ixemul.png]]
 
[[File: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 '''&minus;noixemul''' option has to be added, so the compiler is called as follows:
+
 
 +
It can also be 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 the ''libnix'' alternative is recommended for use of the standard library. To use it, a '''&minus;noixemul''' option has to be added, so the compiler is called as follows:
 +
 
  
 
<tt>gcc -noixemul -o helloworld helloworld.c</tt>
 
<tt>gcc -noixemul -o helloworld helloworld.c</tt>
  
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==
+
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 the executable. Every C handbook states, that ''printf()'' is the most expensive function of standard I/O, which has just been proven experimentally... On the other hand program activity, as traced with ''Snoopium'', is reduced to three entries. No external resources are opened.
 +
 
 +
 
 +
=="Hello World!" With the MorphOS Native API==
 +
 
 +
The 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 the 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 the native API are not portable (except for porting to AmigaOS and AROS to some degree).
 +
* Native ''printf()''-like functions do not support floating point numbers.
 +
 
 +
 
 +
The "Hello World!" example using the native API is as follows:
 +
 
 +
 
 +
<tt>#include <proto/dos.h><br><br>
 +
int main(void)<br>
 +
{<br>
 +
&nbsp;&nbsp;Printf("Hello World!\n");<br>
 +
&nbsp;&nbsp;return 0;<br>
 +
}</tt>
 +
 
 +
 
 +
The included header includes all things needed to use the ''dos.library'', where the ''Printf()'' function is located. The function itself works the same as the standard library ''printf()'', with some minor differences. The code is compiled with this command:
 +
 
 +
 
 +
<tt>gcc -noixemul -o helloworld helloworld.c</tt>
 +
 
 +
 
 +
The command is the same as that used for the program using ''libnix'' and the standard library ''printf()'', however, the standard C function is not used, so it is not linked. Now the executable size reduces to 13 500 bytes.
 +
 
 +
 
 +
Why is ''libnix'' still needed in spite of the standard library calls not being used? Can't one just compile with '''&minus;nostdlib'''? Other than the standard C library, ''libnix'' also provides application startup code. A program without this startup code can still work when launched from the shell, but will crash when started from Ambient. The startup code also provides an automatic MorphOS library opening and closing feature. So, excluding ''libnix'' completely is possible, but requires [[writing your own startup code]] and [[MorphOS_API_and_Its_Organization#Manual_Library_Opening_and_Closing|handling library opening and closing manually]].
 +
 
 +
 
 +
<small>Note: excluding ''libnix'' is usually done for MorphOS components other than applications, like shared libraries or Reggae and MUI public classes. It can also be done for ordinary programs just to make them shorter, especially if a program is small. For bigger projects bytes saved by writing custom startup code are not usually worth the effort.</small>

Latest revision as of 08:15, 19 October 2012

Grzegorz Kraszewski


This page in other languages: Polish


"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 completeness:


#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 the Ambient menu, or using the rcommand + n key combo) and changes current directory to the one, where the C source is located. The compiler is run as follows:


gcc -o helloworld helloworld.c


The compiler produces a helloworld executable, which is 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, it can be done. Traditionally MorphOS executables are named without any extensions. The −o compiler option specifies a 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 provided by ixemul.library. It can be easily confirmed by tracing the disk activity of helloworld using the Snoopium tool.


Snoopium ixemul.png


It can also be 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 the libnix alternative is recommended for use of 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 the executable. Every C handbook states, that printf() is the most expensive function of standard I/O, which has just been proven experimentally... On the other hand program activity, as traced with Snoopium, is reduced to three entries. No external resources are opened.


"Hello World!" With the MorphOS Native API

The 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 the 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 the native API are not portable (except for porting to AmigaOS and AROS to some degree).
  • Native printf()-like functions do not support floating point numbers.


The "Hello World!" example using the native API is 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 the Printf() function is located. The function itself works the same as the standard library printf(), with some minor differences. The code is compiled with this command:


gcc -noixemul -o helloworld helloworld.c


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


Why is libnix still needed in spite of the standard library calls not being used? Can't one just compile with −nostdlib? Other than the standard C library, libnix also provides application startup code. A program without this startup code can still work when launched from the shell, but will crash when started from Ambient. The startup code also provides an automatic MorphOS library opening and closing feature. So, excluding libnix completely is possible, but requires writing your own startup code and handling library opening and closing manually.


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