14 .TH exc 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
16 exc \- exception handling for C programs
33 .B "#include <mLib/exc.h>"
43 .BI "THROW(exc_extype " type
50 .B "typedef void (*exc__uncaught)(exc_extype, exc_exval);"
51 .BI "exc__uncaught exc_uncaught(exc__uncaught " proc );
53 .BI "exc_extype EXC_PAIR(unsigned char " x ", unsigned char " y );
54 .BI "exc_extype EXC_ALLOC(exc_extype " owner ", exc_extype " type );
55 .BI "exc_extype EXC_ALLOCN(exc_extype " owner ", exc_extype " type );
56 .BI "exc_extype EXC_ALLOCI(exc_extype " owner ", exc_extype " type );
57 .BI "exc_extype EXC_ALLOCP(exc_extype " owner ", exc_extype " type );
58 .BI "exc_extype EXC_ALLOCS(exc_extype " owner ", exc_extype " type );
63 introduces some new syntax and definitions to support exception handling
64 in C. The marriage is not particularly successful, although it works
65 well enough in practice.
67 The syntax introduced consists of new
71 statements and a pair of new expression types
75 It's unfortunately important to remember that the syntax is provided
76 using macro expansion and standard C facilities; some of the
77 restrictions of these features show through.
78 .SS "The TRY statement"
81 statement associates an exception handler with a piece of code. The
82 second statement is an
83 .IR "exception handler" .
86 is the duration of the first statement's execution, together with the
87 duration of any functions called within the dynamic scope. (Note in
88 particular that an exception handler is not within its own dynamic
89 scope.) A thrown exception causes the exception handler with
90 dynamically innermost scope to be executed.
92 Two special variables are provided to the exception handler:
97 of the exception caught. This is value of type
104 of the exception. This has a union type, with members
109 Only one of the members is valid; you should be able to work out which
110 from the exception type. There are abbreviations
115 which refer to members of
118 .SS "The EXIT_TRY statement"
119 It is not safe to leave the dynamic scope of an exception handler early
122 statement). You can force a safe exit from a dynamic scope using the
124 statement from within the
129 .SS "The THROW and RETHROW statements"
132 expression throws an exception. The first argument is the type of
133 exception; the second is some data to attach to the exception. The type
134 of data, integer, string or pointer, is determined from the exception
137 Control is immediately passed to the exception handler with the
138 innermost enclosing dynamic scope.
142 expression is only valid within an exception handler. It rethrows the
143 last exception caught by the handler.
150 .SS "Exception type allocation"
151 Exception types are 32-bit values. The top 16 bits are an
152 .IR "owner identifier" .
153 The idea is that each library can have an owner identifier, and it can
154 then allocate exceptions for its own use from the remaining space. Two
155 special owner codes are defined:
157 .B "EXC_GLOBAL (0x0000)"
158 The global space defined for everyone's benefit. Don't define your own
159 exceptions in this space.
161 .B "EXC_SHARED (0xffff)"
162 A shared space. You can use this for any exceptions which won't be seen
165 Other owner codes may be allocated by choosing two characters (probably
166 letters) which best suit your application and applying the
168 macro to them. For example, the owner code for
171 .BR "EXC_PAIR('m', 'L')" ,
174 defined any exceptions other then the global ones.
176 The bottom 16 bits are the actual exception type, and the data type
177 which gets passed around with the exception. The data type is
178 (bizarrely) in bits 6 and 7 of the type word. The data type code is one
182 There is no data associated with this exception.
185 The data is an integer, with type
189 The data is a pointer to some data structure, with type
191 Note that you probably have to do an explicit cast to
198 The data is a pointer to a string of characters, of type
201 If the data to be thrown is a pointer, make sure that the object pointed
202 to has a long enough lifetime for it to actually get to its exception
203 handler intact. In particular, don't pass pointers to automatic
204 variables unless you're
206 they were allocated outside the handler's dynamic scope.
208 Individual exceptions are allocated by the macros
215 The exception has no data
218 The exception data is an integer.
221 The exception data is a pointer.
224 The exception data is a character string.
228 macros take two arguments: the owner code (usually allocated with
230 as described above), and the type code. The data type is encoded into
231 the exception type by the allocation macro.
232 .SS "Predefined exceptions"
233 The following exceptions are predefined:
236 No data. Signals an out-of-memory condition.
239 Integer data. Signals an operating system error. The data is the value
242 associated with the error.
245 Pointer data. Signals a RISC\ OS error. The data is a pointer to the
246 RISC\ OS error block. (Non RISC\ OS programmers don't need to worry
250 Integer data. Signals a raised operating system signal. The data is
254 String data. Signals a miscellaneous failure. The data is a pointer to
255 an explanatory string.
257 The call to an exception handler is achieved using
259 Therefore all the caveats about
261 and automatic data apply. Also, note that status such as the signal
262 mask is not reset, so you might have to do that manually in order to
263 recover from a signal.
267 Mark Wooding, <mdw@distorted.org.uk>