Article View: comp.lang.objective-c
Article #369Exceptions for C and Objective-C
From: Niels M|ller
Date: Tue, 14 Nov 1995 02:14
Date: Tue, 14 Nov 1995 02:14
149 lines
4208 bytes
4208 bytes
Exceptions are something that so far are missing in C and Objective-C.
But it is not too difficult to implement them on top of setjmp(),
portably. In fact, I just did this.
My main reason I wrote this is that I think that the libobjects
Objective-C library desperately needs exceptions. This is the first
version I release, it is still immature and very lightly tested, but
I'd like to hear your comments. Here's the features:
Two interfaces, one for C, and one for Objective-C. You can link
together C code using the C interface and Objective-C code using the
Objective-C interface, without trouble.
From C, you get a few macros, CATCH, THROW and PROTECT, with
functionality similar to catch, throw and unwind-protect in emacs. You
can use them like:
----------------------EXAMPLE 1------------------
int main(int argc, char **argv)
{
int result;
init_catch();
result = CATCH(&tag, {
printf("main ...\n");
call(bar,11);
printf("main, after bar.\n");
17;
});
printf("Back in main, result is %d\n",result);
return 0;
}
void call (void (*fn)(void), int i)
{
PROTECT({
/* This is the body */
printf("Calling...\n");
fn();
},
{
/* This is the cleanup code */
printf("Cleaning up. The number is %d\n", i);
});
printf("Call finished\n");
}
void bar()
{
printf("bar, throwing...\n");
THROW(tag, 17);
printf("Can't happen");
}
----------------------EXAMPLE 1------------------
The Objective-C interface also offers catch, throw and unwind-protect
functionality, by means of the classes Catch and UnwindProtect. The
same example, using Objective-C instead:
----------------------EXAMPLE 2------------------
id tag;
int main(int argc, char **argv)
{
int result;
tag = [Catch new];
if ((result = set_catch([tag catch])) == 0)
{
printf("main ...\n");
call(bar,11);
printf("main, after bar.\n");
result =17;
}
[tag free];
printf("Back in main, result is %d\n",result);
return 0;
}
void call (void (*fn)(void), int i)
{
void cleanup(void)
{
printf("Cleaning up. The number is %d\n", i);
}
id protect = [UnwindProtect new];
[protect cleanupByCalling: cleanup];
printf("Calling...\n");
fn();
[protect cleanup]; /* Freed automatically! */
printf("Call finished\n");
}
void bar()
{
printf("bar, throwing...\n");
[tag throwInt: 17];
printf("Can't happen");
}
----------------------EXAMPLE 2------------------
In addition, the Catch class lets you pass any object up from -throw
to -catch, not only integers.
There are also two classes Error and CatchError. CatchError is similar
to Catch, but let you catch any error of a specific kind. Error is
the root of the error hierarchy, and implements the method -raise.
Of course, raising and catching errors also respect the UnwindProtect
construction.
----------------------EXAMPLE 3------------------
int result;
id tag = [CatchError new];
if ((result = set_catch([catch: ErrorNoMemory])) == 0) { body }
else /* Handle error */
{
id error = [tag error];
...
[error free];
}
[tag free];
...
[[ErrorNoMemory] new] raise]; /* Raise error */
----------------------EXAMPLE 3------------------
You can download it all (about 18K gzipped) from
http://www.lysator.liu.se/~nisse/archive/exceptions-0.3.tar.gz
GNU General Public License apply.
Best regards, and happy hacking!
/Niels MΓΆller
PS. I'll be away to Denmark the rest of this week. I'm looking forward
to reading your mail when I get back.
Technical Details
Message-ID:
<nnrazckkme.fsf@lysistrate.lysator.liu.se>Path:
arc1-ca.pugleaf.net!news.ifm.liu.se!usenetShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.ifm.liu.se!usenet From: nisse@lysator.liu.se (Niels M|ller) Newsgroups: comp.lang.objective-c,comp.lang.c Subject: Exceptions for C and Objective-C Date: 14 Nov 1995 03:14:49 +0100 Organization: Lysator Computer Society, Link|ping University, Sweden Sender: nisse@lysistrate.lysator.liu.se Message-ID: <nnrazckkme.fsf@lysistrate.lysator.liu.se> NNTP-Posting-Host: lysistrate.lysator.liu.se Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Newsreader: Gnus v5.0.8