14 .TH exc 3mLib "20 June 1999" mLib
16 exc \- exception handling for C programs
18 .B "#include <mLib/exc.h>
28 .BI "THROW(exc_extype " type
35 .B "typedef void (*exc__uncaught)(exc_extype, exc_exval);"
36 .BI "exc__uncaught exc_uncaught(exc__uncaught " proc );
38 .BI "exc_extype EXC_PAIR(unsigned char " x ", unsigned char " y );
39 .BI "exc_extype EXC_ALLOC(exc_extype " owner ", exc_extype " type );
40 .BI "exc_extype EXC_ALLOCN(exc_extype " owner ", exc_extype " type );
41 .BI "exc_extype EXC_ALLOCI(exc_extype " owner ", exc_extype " type );
42 .BI "exc_extype EXC_ALLOCP(exc_extype " owner ", exc_extype " type );
43 .BI "exc_extype EXC_ALLOCS(exc_extype " owner ", exc_extype " type );
48 introduces some new syntax and definitions to support exception handling
49 in C. The marriage is not particularly successful, although it works
50 well enough in practice.
52 The syntax introduced consists of new
56 statements and a pair of new expression types
60 It's unfortunately important to remember that the syntax is provided
61 using macro expansion and standard C facilities; some of the
62 restrictions of these features show through.
63 .SS "The TRY statement"
66 statement associates an exception handler with a piece of code. The
67 second statement is an
68 .IR "exception handler" .
71 is the duration of the first statement's execution, together with the
72 duration of any functions called within the dynamic scope. (Note in
73 particular that an exception handler is not within its own dynamic
74 scope.) A thrown exception causes the exception handler with
75 dynamically innermost scope to be executed.
77 Two special variables are provided to the exception handler:
82 of the exception caught. This is value of type
89 of the exception. This has a union type, with members
94 Only one of the members is valid; you should be able to work out which
95 from the exception type. There are abbreviations
100 which refer to members of
103 .SS "The EXIT_TRY statement"
104 It is not safe to leave the dynamic scope of an exception handler early
107 statement). You can force a safe exit from a dynamic scope using the
109 statement from within the
114 .SS "The THROW and RETHROW statements"
117 expression throws an exception. The first argument is the type of
118 exception; the second is some data to attach to the exception. The type
119 of data, integer, string or pointer, is determined from the exception
122 Control is immediately passed to the exception handler with the
123 innermost enclosing dynamic scope.
127 expression is only valid within an exception handler. It rethrows the
128 last exception caught by the handler.
135 .SS "Exception type allocation"
136 Exception types are 32-bit values. The top 16 bits are an
137 .IR "owner identifier" .
138 The idea is that each library can have an owner identifier, and it can
139 then allocate exceptions for its own use from the remaining space. Two
140 special owner codes are defined:
142 .B "EXC_GLOBAL (0x0000)"
143 The global space defined for everyone's benefit. Don't define your own
144 exceptions in this space.
146 .B "EXC_SHARED (0xffff)"
147 A shared space. You can use this for any exceptions which won't be seen
150 Other owner codes may be allocated by choosing two characters (probably
151 letters) which best suit your application and applying the
153 macro to them. For example, the owner code for
156 .BR "EXC_PAIR('m', 'L')" ,
159 defined any exceptions other then the global ones.
161 The bottom 16 bits are the actual exception type, and the data type
162 which gets passed around with the exception. The data type is
163 (bizarrely) in bits 6 and 7 of the type word. The data type code is one
167 There is no data associated with this exception.
170 The data is an integer, with type
174 The data is a pointer to some data structure, with type
176 Note that you probably have to do an explicit cast to
183 The data is a pointer to a string of characters, of type
186 If the data to be thrown is a pointer, make sure that the object pointed
187 to has a long enough lifetime for it to actually get to its exception
188 handler intact. In particular, don't pass pointers to automatic
189 variables unless you're
191 they were allocated outside the handler's dynamic scope.
193 Individual exceptions are allocated by the macros
200 The exception has no data
203 The exception data is an integer.
206 The exception data is a pointer.
209 The exception data is a character string.
213 macros take two arguments: the owner code (usually allocated with
215 as described above), and the type code. The data type is encoded into
216 the exception type by the allocation macro.
217 .SS "Predefined exceptions"
218 The following exceptions are predefined:
221 No data. Signals an out-of-memory condition.
224 Integer data. Signals an operating system error. The data is the value
227 associated with the error.
230 Pointer data. Signals a RISC\ OS error. The data is a pointer to the
231 RISC\ OS error block. (Non RISC\ OS programmers don't need to worry
235 Integer data. Signals a raised operating system signal. The data is
239 String data. Signals a miscellaneous failure. The data is a pointer to
240 an explanatory string.
242 The call to an exception handler is acheived using
244 Therefore all the caveats about
246 and automatic data apply. Also, note that status such as the signal
247 mask is not reset, so you might have to do that manually in order to
248 recover from a signal.
250 Mark Wooding, <mdw@nsict.org>