πŸš€ go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.objective-c
Article #369

Exceptions for C and Objective-C

#369
From: Niels M|ller
Date: Tue, 14 Nov 1995 02:14
149 lines
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!usenet

Show 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