From -6502117779076592242
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,96a8c01f7043c2d9
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2002-09-12 12:40:45 PST
Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news.ems.psu.edu!news.cis.ohio-state.edu!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!kibo.news.demon.net!mutlu.news.demon.net!demon!mail2news.demon.co.uk!devnull
From: pierrebai@hotmail.com (Pierre Baillargeon)
Newsgroups: comp.std.c++
Subject: Re: Proposal: exception stack unwinding resumption
Date: Thu, 12 Sep 2002 19:40:45 +0000 (UTC)
Organization: http://groups.google.com/
Lines: 107
Approved: fjh@cs.mu.oz.au (Fergus Henderson , moderator of comp.std.c++)
Message-ID: <6df0c6a8.0209121133.6f081c37@posting.google.com>
References: <6df0c6a8.0208260746.633710cb@posting.google.com> <zllb9.458$S51.25977@newsfep1-gui.server.ntli.net> <6df0c6a8.0209030656.249192ce@posting.google.com> <tHkd9.24180$5g6.553497@newsfep2-win.server.ntli.net> <6df0c6a8.0209051026.5df687db@posting.google.com> <ar_e9.1193$Yc7.36404@newsfep2-gui> <6df0c6a8.0209100534.619b8531@posting.google.com> <TbHf9.859$Pa7.63089@newsfep1-gui.server.ntli.net>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: mail2news.demon.co.uk 1031859645 6160 10.0.0.1 (12 Sep 2002 19:40:45 GMT)
X-Complaints-To: abuse@demon.net
NNTP-Posting-Date: Thu, 12 Sep 2002 19:40:45 +0000 (UTC)
X-Received: from mulga.cs.mu.oz.au ([128.250.1.22])
	by news.demon.co.uk with esmtp (Exim 4.05)
	id 17pZpT-0001bC-00
	for mail2news@news.news.demon.net; Thu, 12 Sep 2002 19:40:43 +0000
X-Received: from localhost (localhost [[UNIX: localhost]]) by mulga.cs.mu.OZ.AU
	id FAA22966; Fri, 13 Sep 2002 05:40:40 +1000 (EST)
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Path: comp-std-cpp-robomod!not-for-mail
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Delivered-To: std-c++@ncar.ucar.edu
X-Newsgroups: comp.std.c++
X-NNTP-Posting-Date: 12 Sep 2002 19:33:06 GMT
Xref: archiver1.google.com comp.std.c++:13857

I think this thread is beginning to drift toward discussion of my
usage vs std related stuff. It may still be relevant as an example of
use...

glancaster@ntlworld.com ("Garry Lancaster") wrote in message news:<TbHf9.859$Pa7.63089@newsfep1-gui.server.ntli.net>...
>
> void foo() {
>     DocumentSection d; // ctor does header, dtor footer.
>     write_body();    // throws!
> }
> 
> Even if the destructor succeeds, the footer will
> likely appear in the wrong place since the whole
> of the body may not have been written before the
> exception was thrown. If the destructor fails, the
> program will, by default, terminate. Mucking
> around with uncaught_exception or similar may
> change the exact behaviour, but it will still be a
> hard-to-understand mess.

In the particular example you give, the footer will be at the right
place, but the body content will be bad. But the current design is
that the PDF document must be all valid: an error output in a single
object makes the document invalid and it gets deleted.

But the fact is that the design also support erasing invalid PDF
file-objects. That capability is there because some usage of the PDF
framework sometimes realize in the middle of an object that the object
is not needed after all. This capability could be used in destructors
to remove invalid file-objects by detecting that an exception is in
flight. I have no use for this now though.

> 
> There are other ways to automatically bracket
> a pre- and post- operation that don't suffer from
> these issues. For example, the Template Method
> pattern from Gamma et al.'s "Design Patterns",
> which can be implemented using virtual functions
> (as in the book) or C++ templates (shown below).
> 
> void foo() {
>       DocumentSection d;    // Ctor and dtor now simple.
>       d( write_body );
> }
> 
> template <typename BodyWriter>
> void DocumentSection::operator()(BodyWriter f) {
>     write_header();
>     f();
>     write_footer();
> }
>  

Yes, I know of this pattern and it actually used in the RAII classes
to write the header and footer! The basic design is:

struct Writable
{
   virtual void begin_write(...) = 0;
   virtual void write(...) = 0;
   virtual void end_write(...) = 0;
};

struct Writer
{
   Writer( Writable & aWr ) : wr ( aWr )
   {
      wr.begin_write();
   }

   ~Writer()
   {
      wr.end_write();
   }
};

The problem with the your implementation is that the body, f() in your
code, has to be written in a derived classes. This disperses the code,
making it unreadable. It also requires writing a function for every
usage, making it hard to use. Also consider the requirement that
multiple levels of imbrication must be supported. Here's a typical
fictional example (include and namespace omited):

int main()
{
   PDF pdf("hello.pdf");
   Page page(pdf);
   Stream content(pdf);
   page[Name::Contents] = Ref<Stream>(content);
   FlateEncoder flate(content);
   ASCII85Encoder a85(flate)
   Writer writer1(a85);
   writer << "(Hello World!) Tj\n";
   Writer writer2(page);
}

Note that your suggestion would not suffer from usability problem if
it were possible to write local class that have access to the local
variable of the enclosing function. The code would still be less
readable IMO.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



