C in RISC OS


Introduction

The workings of C with RISC OS and its interactions with various libraries often raise many questions. All too often these questions are incompletely answered, leading to more questions or confusion. This document attempts for the first time to fully explain all the concepts in an understandable way.

Standards

C is defined by a number of standards. Probably the most important one is the ANSI C standard. Among other things, this defines what functionality must be present in a standard C library implementation. When the "Shared C Library" is referred to on RISC OS we are talking about the library developed by Acorn which is ANSI compliant.

The Shared C Library (SCL) resides in a module in ROM (or RAM if it's softloaded) and is called by C programs linked to it via "stubs" (see below). It also provides other functionality required by a C program such as stack extension and general environment interaction.

POSIX is another standard which defines a considerable number of behaviour characteristics of Unix operating systems. Since these are invarialy C-based, it also defines many C functions that should be provided by a POSIX-compliant system.

The SCL makes no attempt to implement any functions beyond those defined by ANSI - indeed it was never intended that it should - but UnixLib does implement many of these, along with all the functions found in the SCL. Because of this, UnixLib can be invaluable when making Unix programs work on RISC OS

While it is certain that UnixLib doesn't conform fully to POSIX, it makes a good effort, and it is being improved all the time.

Programs and Libraries

When a program is linked (the final stage where the executable is produced), the program will be linked to one of two things - SCL stubs, or UnixLib.

Stubs are a small piece of code that is accessed by your program when making a function call to a C function in the SCL occurs for the first time. Stubs "fix up" the call, and point it directly at the appropriate code in the SharedCLibrary module. The advantage of this is that the code is shared by all callers, and not duplicated for all programs. It also means that when a bug fix occurs, all programs benefit.

On the other hand, when a program is linked to UnixLib, all the library code used by a program from Unixlib is attached to your program. This explains why UnixLib programs end up bigger than ones linked with SCL. This is referred to as statically linked.

There is one exception to this. UnixLib relies on the module SharedUnixLibrary. This module implements a small amount of functionality that cannont safely be put into an application. It is hoped that one day more functionality will move into this module to give the same advantages that the SCL module does.

Compilers and Libraries

By default, Norcroft uses the SharedCLibrary, and GCC uses UnixLib. LCC also uses SharedCLibrary by default.

In some cases, it's appropriate that the compiler use the alternate library. As with all libraries, these are split into the library's headers which advertise their functionality, and the library itself, which contains the code. The following describes use of each library with the 3 compilers

In bigger programs, compiling and linking is usually split into two operations. You should ensure that you use the same flags at each point, otherwise you will have unexpected results.

Mixing Libraries and Compilers

Sometimes it is convenient to try and mix object files or libraries compiled with one compiler or targeted against different C libraries.

In general, I would discourage this, unless you know what you are doing. The reasons are as follows:

This is not to say that mixing output is not impossible - it is, with care, but you should take note of the differences.