From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13132 invoked by alias); 26 Sep 2011 21:01:40 -0000 Mailing-List: contact archer-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: List-Id: Received: (qmail 13123 invoked by uid 22791); 26 Sep 2011 21:01:39 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org MIME-Version: 1.0 In-Reply-To: References: Date: Mon, 26 Sep 2011 21:01:00 -0000 Message-ID: Subject: Re: C++ draft From: Jim Blandy To: Tom Tromey Cc: Project Archer Content-Type: text/plain; charset=ISO-8859-1 X-SW-Source: 2011-q3/txt/msg00007.txt.bz2 I came across this thread, and thought I might bring up Mozilla's experience converting our JavaScript engine to C++. (It seems like this discussion hasn't moved over to the gdb mailing list, so I'm sending this here.) C++'s richer type system is wonderful. We try to get strict typing everywhere we can, and it has helped a lot. Legibility is way up since I started at Mozilla, in 2008, just before we switched. Contrary to your plan, we did *not* use C++ exceptions, but stuck with our primitive "false/NULL return value means error; please clean up and propagate" system (we carry details about the error in a structure off to the side). It's actually a lot of work to transition C code to being robust in the presence of exceptions. Pretty much every place you call malloc/realloc needs to use some kind of automatic clean-up facility like std::auto_ptr, unless you're positive nobody will ever add a call to a function that might throw an exception before that malloc'd storage is freed, or linked into whatever data structure it's destined for, or the like. The essential problem is that the old C code, by explicitly propagating the errors, effectively makes a big, visible distinction between calls that might throw, and calls that won't. All the control flow is explicit. When you switch to exceptions, that distinction goes away: any call could potentially leave the scope, and every pointer that's live across that call must be prepared for the possibility. We do use RAII a lot, though; that works great, and is a big win, even when the code propagates errors explicitly. Constructors and destructors are extremely helpful for all sorts of things. One thing that surprised me is that we have a lot of little classes that are only used for local variables, never allocated on the heap. We use them to abstract out common patterns of code that occur *within functions*. Because inlining is trustworthy in G++, the generated code doesn't change much, but it's much more legible.