public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Mark Mitchell <mark@codesourcery.com>
Cc: Mike Stump <mrs@apple.com>,
	gcc@gcc.gnu.org, Jason Merrill <jason@redhat.com>
Subject: Re: __attribute__((cleanup(function)) versus try/finally
Date: Thu, 08 May 2003 19:37:00 -0000	[thread overview]
Message-ID: <wvlof2d2ptj.fsf@prospero.boston.redhat.com> (raw)
In-Reply-To: <1052419221.3329.111.camel@minax.codesourcery.com> (Mark Mitchell's message of "08 May 2003 11:40:21 -0700")

On 08 May 2003 11:40:21 -0700, Mark Mitchell <mark@codesourcery.com> wrote:

> If we were designing a new language, I'd certainly agree with you that
> exceptions are a good feature.  When discussing C on a workstation-class
> machine, I'd be more likely to agree with you, even though I think
> adding exceptions to C is antithetical of that language's key design
> goals. 
>
> When discussing C for embedded systems, though, I just can't see it.  I
> fully concede that my scheme is less beautiful -- unless you see beauty
> in the number of bytes saved.

I argued in my last reply that sjlj EH can have the same cost as the
existing pthread cleanup mechanism.  Do you disagree?

> I think what really happened here was that the pthreads designers wanted
> to add pthread_atexit -- and then got carried away.

I think they wanted exactly what they wrote.  atexit isn't useful for
cleanups of a fixed duration.

> (In fact, so far as I can tell, a careful reading of
>
>   http://www.unix.org/single_unix_specification/
>
> would suggest that:
>
>   pthread_cleanup_push (f, a);
>   goto l;
>   pthread_cleanup_pop (1);
>  l:
>
> is well-defined, and does not result in the cleanup being executed. 
> Presumably, this should be undefined behavior, as it does not work at
> all with the sample implementation in the specification.

Agreed.

> The question of whether pthread_cleanup_push should create a new scope
> is also important, at least in C99 and C++: is
>
>    int i;
>    pthread_cleanup_push (f, a);
>    int i;
>
> valid, or not, or is this unspecified?)

I'd say unspecified or valid.  The spec talks about implementation as
macros containing { and }.

> Also, doesn't the execute argument to pthread_cleanup_pop mean that
> try/finally isn't the right construct?  
>
> I would think that the EH version of:
>
>   pthread_cleanup_push (f, a);
>   g ();
>   pthread_cleanup_pop (x);
>
> would be:
>
>   try {
>     g();
>   } catch (...) {
>     f(a);
>     throw;
>   }
>   if (x) f(a);

Hard to do that with macros; you need to store the push args into temporary
variables.  You'd need to do something like

  {
    void (*_f)(void *) = f;
    void *_a = a;

    try {
      g();
    } catch (...) {
      _f (_a);
      throw;
    }
    if (x) _f (_a);
  }

but nobody's advocating adding catch to C, are they?  Besides,
catch/rethrow is more expensive than running a cleanup.

A try/finally implementation would look like

  {
    void (*_f)(void *) = f;
    void *_a = a;
    int _x = 1;

    try {
      g ();
      _x = x;
    } finally {
      if (_x) _f (_a);
    }
  }

An implementation using C++ destructors would work similarly:

  struct cleanup {
    void (*_f)(void *);
    void *_a;
    bool _x;

    cleanup (void (*fn)(void *), void *arg): _f (fn), _a (arg), _x (true) {}
    ~cleanup () { if (_x) _f(_a); }
  };
  ...
  {
    cleanup c (f, a);

    g ();

    c._x = x;
  }

Or, using attribute (cleanup):

  struct cleanup {
    void (*_f)(void *);
    void *_a;
    int _x;
  };

  void cleanup_dtor (struct cleanup *p)
  {
    if (p->_x) (p->_f)(p->_a);
  }
  ...
  {
    struct cleanup c __attribute ((__cleanup (cleanup_dtor)))
      = { f, a, 1 };

    g ();

    c._x = x;
  }

Any of these would do the job.  All of them involve adding EH to C.
I think that try/finally is the most elegant way to do that.

Jason

  parent reply	other threads:[~2003-05-08 19:37 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.BSF.4.55.0305061457450.57349@acrux.dbai.tuwien.ac.at>
     [not found] ` <1052245742.2583.315.camel@doubledemon.codesourcery.com>
     [not found]   ` <wvlissnc2e3.fsf@prospero.boston.redhat.com>
     [not found]     ` <1052249890.31850.338.camel@doubledemon.codesourcery.com>
2003-05-06 21:04       ` Jason Merrill
2003-05-06 21:24         ` Mark Mitchell
2003-05-07 21:21           ` Jason Merrill
2003-05-07 22:18             ` Mark Mitchell
2003-05-07 23:01               ` Jason Merrill
2003-05-08 12:05               ` Gabriel Dos Reis
2003-05-09  5:46               ` Kai Henningsen
2003-05-06 21:52         ` Anthony Green
2003-05-08 17:44         ` Mike Stump
2003-05-08 17:45           ` Jason Merrill
2003-05-08 18:40             ` Mark Mitchell
2003-05-08 19:06               ` Alexandre Oliva
2003-05-08 19:47                 ` Mark Mitchell
2003-05-08 20:19                   ` Alexandre Oliva
2003-05-08 21:18                   ` Jason Merrill
2003-05-13 21:10                     ` Mark Mitchell
2003-05-13 21:25                       ` Richard Henderson
2003-05-13 21:41                         ` Mark Mitchell
2003-05-13 22:16                           ` Richard Henderson
2003-05-13 21:31                       ` Gabriel Dos Reis
2003-05-15 17:00                       ` Jason Merrill
2003-05-15 17:23                         ` Mark Mitchell
2003-05-09 19:41                   ` Kai Henningsen
2003-05-08 19:37               ` Jason Merrill [this message]
2003-05-07  0:14   ` Richard Henderson
2003-05-07  2:32     ` Mark Mitchell
2003-05-13 21:33 Richard Kenner
2003-05-13 22:11 ` Richard Henderson
  -- strict thread matches above, loose matches on Subject: below --
2003-05-09  9:54 Ranjit Mathew
2003-05-09 10:16 ` Andrew Haley
2003-05-09 12:08   ` Fergus Henderson
2003-05-09 12:49   ` Jamie Lokier
2003-05-09  9:23 Ranjit Mathew
2003-05-09  9:31 ` Andrew Haley
2003-05-08  7:49 Ranjit Mathew
2003-05-08 21:21 ` Richard Henderson
2003-05-07 10:18 Ranjit Mathew
2003-05-07 13:54 ` Jason Merrill
2003-05-07 18:23 ` Richard Henderson
2003-05-08 18:02 ` Mike Stump
2003-05-06 19:56 Jason Merrill
2003-05-08 11:59 ` Gabriel Dos Reis
2003-05-08 15:02   ` Jason Merrill
2003-05-08 18:30 ` Mike Stump
2003-05-08 20:49   ` Richard Henderson
2003-05-08 22:29     ` Mike Stump
2003-05-13  0:07       ` Geoff Keating
2003-05-13 21:27         ` Richard Henderson
2003-05-14  1:14           ` Geoff Keating
2003-05-14  7:41             ` Richard Henderson
2003-05-14 21:11               ` Geoff Keating
2003-05-14 22:20                 ` Richard Henderson

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=wvlof2d2ptj.fsf@prospero.boston.redhat.com \
    --to=jason@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=mark@codesourcery.com \
    --cc=mrs@apple.com \
    /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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).