From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23352 invoked by alias); 19 Mar 2008 19:09:36 -0000 Received: (qmail 23343 invoked by uid 22791); 19 Mar 2008 19:09:35 -0000 X-Spam-Check-By: sourceware.org Received: from rn-out-0910.google.com (HELO rn-out-0910.google.com) (64.233.170.191) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 19 Mar 2008 19:09:10 +0000 Received: by rn-out-0910.google.com with SMTP id s46so485278rnb.14 for ; Wed, 19 Mar 2008 12:09:08 -0700 (PDT) Received: by 10.115.32.1 with SMTP id k1mr1919643waj.107.1205953325647; Wed, 19 Mar 2008 12:02:05 -0700 (PDT) Received: by 10.114.120.5 with HTTP; Wed, 19 Mar 2008 12:02:05 -0700 (PDT) Message-ID: Date: Wed, 19 Mar 2008 19:09:00 -0000 From: "Jason Cipriani" To: me22 Subject: Re: try, finally Cc: gcc-help@gcc.gnu.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2008-03/txt/msg00182.txt.bz2 > On Wed, Mar 19, 2008 at 12:13 PM, Jason Cipriani > wrote: > > > Does GCC have anything similar to the MS and Borland compiler's __try > > and __finally keywords? When using GCC I often find that I have code > > like this (a moderately complex, and highly contrived, example): Thanks for your responses, guys. On Wed, Mar 19, 2008 at 12:37 PM, Brian Dessent wrote: > Adding SEH support to gcc has been tossed around for years but nothing > usable has yet to come of it. You can still use SEH through > SetUnhandledExceptionFilter() or by manipulating the exception chain at > %fs:0 manually, but there is no built in compiler support for it. Oh well. Maybe some day. Thanks for the tips. I probably won't do anything like messing with SetUnhandledExceptionFilter(), mostly I just want to simplify code in common situations, I don't want to do anything *too* strange, though. On Wed, Mar 19, 2008 at 1:02 PM, Tim Prince wrote: > The w32api headers in cygwin replicate some of this functionality. Thanks. I'll check those out just to see how they do it, but I'm actually doing Linux development at the moment, and on Windows I usually use MinGW GCC. On Wed, Mar 19, 2008 at 1:30 PM, Ted Byers wrote: > What you say suggests you ought to take an hour or two > to study RAII (resource acquisition is > initialization), and see how far that allows you to > clean up obviously problematic code. Agreed; I know the idiom but I've been always avoided the std and boost RAII utilities for some reason -- however, it's 2008 and probably about time for me to bite the bullet, especially with C++0x coming out some day, I have no excuse. One situation I frequently find myself in is something like: "Ugh... I want to write this code and I really don't feel like implementing everything required to make resource cleanup automatic here; I'll just put cleanup code everywhere instead". In reality, those things are already written, I guess. me22 wrote: > Why bother with void* and C? Just an example. So, WRT what Ted Byers and me22 said, an issue I typically have that I always assumed the std / boost utilities couldn't handle (and hence one reason why I never bother looking into them), is that it's not always as simple as creating objects with new and delete. For example, some code I recently wrote (and what prompted me to ask this question) used libxml2, a C library, from my C++ code; say something like this (if you are actually familiar with libxml2; I made up the FindChildNode function): ===== xmlDoc *doc = NULL; xmlNode *root, *node; xmlChar *str1 = NULL, *str2 = NULL, *str3 = NULL; // load document, fail on error if (!(doc = xmlReadFile(...))) throw Something(); try { // get root xml node, fail if document is empty if (!(root = xmlDocGetRootElement(doc))) throw Something(); // get "first" node string into str1, fail on error if (!(node = FindChildNode(root, "first"))) throw Something(); if (!(str1 = xmlNodeGetContent(node))) throw Something(); // get "second" node string into str2, fail on error if (!(node = FindChildNode(root, "second"))) throw Something(); if (!(str2 = xmlNodeGetContent(node))) throw Something(); // get "third" node string into str3, fail on error if (!(node = FindChildNode(root, "third"))) throw Something(); if (!(str3 = xmlNodeGetContent(node))) throw Something(); // do something with str1, str2, str3 } catch (...) { xmlFree(str3); xmlFree(str2); xmlFree(str1); xmlFreeDoc(doc); xmlCleanupParser(); throw; } // and duplicate cleanup code: xmlFree(str3); xmlFree(str2); xmlFree(str1); xmlFreeDoc(doc); xmlCleanupParser(); ===== Now, in this specific example: there are a few other third-party libraries available that provide C++ bindings to libxml2 -- let's say that for whatever reason they are not acceptable here. And in the general case, the cleanup code here is not "deleting" something, they are custom cleanup functions that I have no control over. If my goal is to reduce the amount of coding I have to do, it is far easier for me to duplicate the cleanup code than to go and write a bunch of small C++ wrapper objects with automatic cleanup that I can use interchangeably with the libxml2 data types. Does std or boost have some kind of "smart pointers" that let me define the cleanup actions without having to write too much additional code? Thanks, Jason