all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Joel Yliluoma <bisqwit@iki.fi>
To: help-gnu-emacs@gnu.org
Subject: Re: How to exit out of a function ? what is try-catch-throw in terms of Program Counter
Date: 23 Oct 2007 09:04:24 GMT	[thread overview]
Message-ID: <slrnfhrea0.sin.bisqwit@bisqwit.iki.fi> (raw)
In-Reply-To: 1192913158.922454.108100@k35g2000prh.googlegroups.com

On Sat, 20 Oct 2007 20:45:58 -0000, gnuist006@gmail.com wrote:
> NOTE: I am really afraid of try-catch-throw. I have never been
> able to understand it since it does not exist in C and I cant
> really visualize the construct in terms of C.

How try-catch-throw is actually implemented depends on the compiler,
but one can explain it like this.

Assume the following C++ code is written:

  #include <cstdio>

  // here's a sample object with a constructor and destructor
  // to demonstrate scope.
  class someobj
  {
  public:
      someobj() { std::puts("constructor"); }
      ~someobj() { std::puts("destructor"); }
  private:
      int x; // a dummy member variable
  };
  
  // A dummy type, it could be a typedef of int or whatever.
  // Just for the purpose of throwing an exception of this particular type.
  struct someexceptiontype
  {
  };

  void code_that_may_throw()
  {
      someobj obj; // instantiating someobj in this scope.
      
      if(false != true)
      {
          // some error situation happened, throw an exception.
          //  someexceptiontype() instantiates an object of
          //  "someexceptiontype" (without binding it into a variable),
          //  and throw throws it.
          throw someexceptiontype();
      }
      
      std::puts("wow, false is true");
  }
  
  void some_intermediate_function()
  {
      std::puts("1");
      code_that_may_throw();
      std::puts("2");
  }
  
  int main()
  {
      try
      {
          some_intermediate_function();
          std::puts("executed without hitch");
      }
      catch(int e)
      {
          std::puts("caught an int");
      }
      catch(someexceptiontype e)
      {
          std::puts("caught someexceptiontype");
      }
      std::puts("end of main()");
      return 0;
  }

The code above contains high-level concepts that approximately translate
to the following lower-level concepts in C. It could be implemented
differently, but the function is the same.

  #include <stdio.h>
  
  typedef struct someobj
  {
      int x;
  } someobj;
  
  void someobj__construct(someobj* this)
  {
      puts("constructor");
      if(__system_exception_ptr) goto __scope_end;
  __scope_end: ;
  }
  void someobj__destruct(someobj* this)
  {
      puts("destructor");
      if(__system_exception_ptr) goto __scope_end;
  __scope_end: ;
  }
  
  struct someexceptiontype
  {
  };
  
  /*** This global code is defined in some system library by the compiler */
  void* __system_exception_ptr  = (void*)0;
  int   __system_exception_type = 0;
  void __clear_exception()
  {
      __system_exception_type = 0;
      free(__system_exception_ptr);
      __system_exception_ptr = (void*)0;
  }
  /*** End of compiler library code */

  void code_that_may_throw(void)
  {
      someobj obj; // instantiating someobj in this scope.
      someobj__construct(&obj);
      if(__system_exception_ptr) goto __scope_end_before_obj;
      
      if(0 != 1)
      {
          someexceptiontype* e = (someexceptiontype*) malloc(sizeof(*e));
          __system_exception_ptr  = e;
          __system_exception_type = 2;
          /* ^ a compiler-specific tag that identifies the exception type */
          goto __scope_end;
      }
      
      puts("wow, false is true");
      if(__system_exception_ptr) goto __scope_end;
      
  __scope_end: ;
      someobj__destruct(&obj);
  __scope_end_before_obj: ;
  }
  
  void some_intermediate_function(void)
  {
      puts("1");
      if(__system_exception_ptr) goto __scope_end;
      
      code_that_may_throw();
      if(__system_exception_ptr) goto __scope_end;
      
      puts("2");
      if(__system_exception_ptr) goto __scope_end;
  __scope_end: ;
  }
  
  int main(void)
  {
      some_intermediate_function();
      if(__system_exception_ptr) goto try_catch;
      puts("executed without hitch");
      if(__system_exception_ptr) goto try_catch;
      goto past_catch;
  try_catch: ;
      switch(__system_exception_type)
      {
          case 1: /* example denoting int type */
          {
              __clear_exception();
              puts("caught an int");
	      if(__system_exception_ptr) goto __scope_end;
              break;
          }
          case 2: /* example denoting someexceptiontype */
          {
              __clear_exception();
              puts("caught someexceptiontype");
	      if(__system_exception_ptr) goto __scope_end;
              break;
          }
          default:
              goto __scope_end; /* still not caught */
      }
  past_catch: ;
      puts("end of main()");
      if(__system_exception_ptr) goto __scope_end;
  
  __scope_end: ;
      return 0;
  }

Of course, for efficiency reasons there is no "if" test after every
function return for exceptions (rather, execution may be transferred
to a dedicated stack and scope unfolder when an exception happens),
but this was the easiest way to explain what happens as regards for
scopes and execution paths.
Also, in the exception handler (catch {}), the exception object is
not supposed to be deallocated until the end of the handler, but
for simplicity I wrote the deallocation first.

Followups set to comp.lang.c++ .

-- 
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)

  parent reply	other threads:[~2007-10-23  9:04 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-20 20:45 How to exit out of a function ? what is try-catch-throw in terms of Program Counter gnuist006
2007-10-20 20:57 ` gnuist006
2007-10-20 22:55 ` Alf P. Steinbach
2007-10-23 18:06   ` gnuist006
2007-10-23 19:53     ` Alf P. Steinbach
2007-11-04 23:02   ` David Thompson
2007-11-05  5:07     ` Alf P. Steinbach
2007-11-05  5:59       ` Alf P. Steinbach
2007-12-02 23:20       ` David Thompson
2007-12-02 23:51         ` Alf P. Steinbach
2007-10-21  1:08 ` Jim Langston
2007-10-21  2:30 ` Keith Thompson
2007-10-21 10:44   ` Kenny McCormack
2007-10-21 10:55     ` santosh
2007-10-21 12:26       ` Richard Heathfield
2007-10-21 22:35       ` Mark McIntyre
2007-10-21 12:09     ` Malcolm McLean
2007-10-21 15:23       ` Kenny McCormack
2007-10-21 15:54         ` santosh
2007-10-21 17:39         ` Malcolm McLean
2007-10-21 21:53           ` Kenny McCormack
2007-10-21  8:03 ` Malcolm McLean
2007-10-21 16:07 ` abhy
2007-10-21 17:43   ` santosh
2007-10-23  9:04 ` Joel Yliluoma [this message]
2007-10-23 16:33 ` Stefan Monnier
2007-10-23 16:44   ` gnuist006
2007-10-23 16:45   ` Victor Bazarov
2007-10-24  1:06     ` Stefan Monnier
2007-10-23 16:54   ` gnuist006
2007-10-23 17:14     ` Alf P. Steinbach
2007-10-24  1:09     ` Stefan Monnier
2007-10-24  0:02   ` Joel Yliluoma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=slrnfhrea0.sin.bisqwit@bisqwit.iki.fi \
    --to=bisqwit@iki.fi \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.