RISC OS C Programming FAQ
From RISC OS
This page aims to answer some of the common questions regarding using C in RISC OS.
Where can I ask questions about a programming problem?
Questions relating to the RISC OS version of GCC should be asked on the GCCSDK mailing list. More general RISC OS programming questions can be asked on the comp.sys.acorn.programmer Usenet group or Iconbar programming forum.
Where can I find the latest version of GCC for RISC OS?
The latest release is available from the GCCSDK page. Experimental versions may also be available there.
How do I call a SWI in C?
In the first instance, don't. Instead, you should use a library which provides an interface to the SWI - this will give you better type checking, and minimise any mistakes. OSLib provides such an interface to call most RISC OS SWIs.
If you still need to call a SWI, then you can use the
_kernel_swi functions provided by SharedCLibrary and Unixlib. Alternatively, you may find it easier to use a SWI library such as DeskLib.
Why are C++ programs with GCC so big?
Firstly, GCC programs by default link with UnixLib, which is statically linked to your program. There is a minimum of about 80k added to your code. Also, some types of C++ programming, especially use of templates, generates large amounts of output. Additionally, some types of template construct generate repeated code due to limitations of the AOF format. Finally, ensure you've got optimization turned on with a -O flag.
Can C++ programs with GCC link with the SharedCLibrary?
Yes, recent versions of GCC support linking C++ with the SharedCLibrary; this may be useful to reduce the size of your output.
Can GCC create modules?
Recent versions of GCC and its toolchain have full module support. It will produce appropriate code with the -mmodule and -mlibscl flags.
My module with floating point code crashes/aborts
Floating point instructions did not work correctly in modules until RISC OS 5 and RISC OS Select. It is possible to configure GCC to build with a software floating point library instead (the
-msoft-float option), but this requires libgcc (a part of GCC) to be built with this option and so isn't available unless you rebuild GCC yourself.
Where can I get GNU Make/other tools for RISC OS?
'make' is available as a RiscPkg package which can be found at http://www.riscos.info/packages/ABCIndex.html, along with other tools including find, gzip, grep, etc.
Is GCC/UnixLib 32-bit Ready?
All versions of GCC have been 32-bit compatible for a number of years. Producing 26-bit code is currently still possible but no longer supported and marked as deprecated.
Can UnixLib be used on RISC OS 3 (3.1, 3.5 - 3.7), ARM2/3?
UnixLib is currently targeted for RISC OS 4 (Select, Adjust included) and RISC OS 5. We believe it can be reasonably used on RISC OS 3 (3.5 - 3.7) but because its developers do not test UnixLib on RISC OS 3 it is almost certain there are issues which are not present when running on RISC OS 4 or 5. Fixing those issues will not a priority but if good & reasonable patches are offered dealing with these issue, they will be considered to be included in the UnixLib source tree (note that in the longer term, any RISC OS 3 support can be dropped on purpose in order to make support for future version or features easier).
Using UnixLib on RISC OS 3.1 is even more challenging for the user and untested/unsupported by its developers as UnixLib assumes for certain functionality the ARM instruction set is at least ARM7 core (ARMv4).
Possible issues with UnixLib on pre-RISC OS 4 and 5 :
- Some assembler source code are using long multiply instructions (not present until ARM7) and SWP instruction (not present in ARM2).
- The runtime stack designed for later OS versions.
- UnixLib uses the DDEUtils module which is know to have several issues in RISC OS 3 releases.
- Current UnixLib is only provided in APCS-32 which should work on RISC OS 3.1 but for the fact that their code is intended for ARM6 and above.
Can SharedCLibrary be used on RISC OS 3 (3.1, 3.5 - 3.7), ARM2/3?
Current GCCSDK releases allow you to use the SharedCLibrary as runtime library when you specify -mlibscl option. This is only supported for APCS-32 output of GCC (the default output) and for APCS-32 compliant SharedCLibrary (modules versions 5.xx). This is the case for Castle Technology SharedCLibrary (supported RISC OS versions are 3.6, 3.7, 4 (including Select & Adjust), 5 and 6) including the 32-bit RISC OS releases of RISCOS Ltd.
So this basically means that you can not use the SharedCLibrary for RISC OS 3.1 and 3.5 in your GCC compiled programs.
Note that the SharedCLibrary module is used by making use of so-called 'stubs'. This is a relatively small AOF library file (or ELF library file in case of GCCSDK 4) offering a sort of trampoline for your code into the SharedCLibrary module and back. GCCSDK provides you an APCS-32 compliant stub which also fulfills typical GCC needs. There are alternative stubs :
- the stubs delivered with Norcroft C/C++ compiler : as this stub is not freely distributable, this is not an option to use. Also facts and experiences are missing if this can really be used by GCC (we doubt it would be a smooth ride).
- GStubs : the current available GStubs version contains a couple of issues for a worry-free GCC usage. So currently this is not an option either. A second release of GStubs is foreseen but it is currently unsure if this is going to be usable for GCC or not.
- Graham Shaw's stubs : is not yet available but is supposed to be open source and usable for the built-in SharedCLibrary (26-bit / 32-bit RISC OS versions) and the Castle Technology SharedCLibrary (APCS-32 version for RISC OS 3.6, 3.7, 4).
Will GCC build code for ARM2/3?
GCCSDK releases based on GCC 3 have by default APCS-32 output selected which is in principle usable on ARM2 and ARM3. Using the option -mapcs-26 you can select the older APCS-R version which was the common APCS flavour for ARM2/3 RISC OS machines. However, there is currently no runtime library delivered in the GCCSDK kit (UnixLib nor the SharedCLibrary stubs delivered with GCCSDK) which is APCS-R compliant. They are all APCS-32 based.
Note that when you select a specific CPU or architecture you might implicitly select APCS-R as well which is not overridable when selecting -mapcs-32. This is the case for -mcpu=arm2, -mcpu=arm3, -march=armv2 and -march=armv2a. When you want garanteed ARM3 instruction compatibility and APCS-32 output, you can use the trick to specify -march=armv3. Further information is on the GCC_processor page.
Note also that the -mapcs-26 (APCS-R) output is currently deprecated in GCC and will be removed from future GCC and GCCSDK releases.
Now to answer this question : GCC 2.95.4 was the last release using supported 26 bit APCS-R. This is recommended if you are targeting RISC OS 3.1 alone but realise that you are taking a huge stepback in functionality and fixes. Using a current GCC version means that you need to find a runtime library which is GCC compatible and runs on RISC OS 3.1. UnixLib might work but has almost garanteed issues which do not appear of later RISC OS version. Using SharedCLibrary requires a stub supporting RISC OS 3.1 which is not the case for the GCCSDKk provided stub.
Is there a GCC tutorial for RISC OS?
riscos.info has a basic GCC tutorial.
What are 'Type 5' errors?
These are uncaught signals received by the SharedCLibrary C runtime system:
Type 1 (SIGABRT) - abort Type 2 (SIGFPE) - arithmetic exception Type 3 (SIGILL) - illegal instruction Type 4 (SIGINT) - attention request from user Type 5 (SIGSEGV) - bad memory access Type 6 (SIGTERM) - termination request Type 7 (SIGSTAK) - stack overflow
Type 5 is the same as 'Segmentation fault' on Unix: the program tried to access some memory it wasn't permitted to. Usually this is the result of trying to dereference null pointers or other programming errors.
How do I write Makefiles?
Firstly, don't use Acorn's !Make tool. It produces terrible Makefiles that are sometimes incompatible with non-Acorn tools, and you haven't a hope of being able to build them on another platform (with GCCSDK, say).
Tony Houghton has written a guide to writing Makefiles by hand. While it leans towards writing them for Acorn's tools such hand-written Makefiles should function cross-platform with a few tweaks. For compatibility it's recommended to refer to files in the Unix form program.o rather than the RISC OS convention o.program
Otherwise there are many tutorials on Makefiles for other platforms. A good cross-platform Makefile should work with Acorn's AMU or GNU Make on RISC OS without problems.
How are C libraries implemented in RISC OS?
The methods of using C libraries in RISC OS are documented in this own comprehensive article.