User: Password:
|
|
Subscribe / Log in / New account

No thanks.

No thanks.

Posted Nov 10, 2012 10:21 UTC (Sat) by paulj (subscriber, #341)
In reply to: No thanks. by Cyberax
Parent article: Haley: We're doing an ARM64 OpenJDK port!

There you go again saying "Nope" to something that is factually correct. At this stage it's hard to conclude anything other than that you simply don't understand how exceptions work under the hood.


(Log in to post comments)

No thanks.

Posted Nov 10, 2012 16:10 UTC (Sat) by nix (subscriber, #2304) [Link]

It's clear he's never written any significant body of exception-safe code in C++, that's for sure. (Hint, Cyberax: consider a simple RAII object which allocates some memory in its constructor, in two tranches, with a single assignment between. Now consider that memory allocation can throw bad_alloc, as can the invocation of the assignment operator, if not elided by the compiler, as it can sometimes be -- and consider that if this is templated, you have to consider that *every possible point* that might throw exceptions, will throw exceptions, since you don't know what types you'll eventually be dealing with.

That memory allocation is not a shared resource except inasmuch as the heap is shared -- in which case you have to consider almost *everything* a use of a shared resource -- but you still need to consider the semantics of exceptions in order to figure out how to avoid a memory leak. And this soon gets thoroughly unobvious.)

No thanks.

Posted Nov 10, 2012 21:48 UTC (Sat) by Cyberax (✭ supporter ✭, #52523) [Link]

>Hint, Cyberax: consider a simple RAII object which allocates some memory in its constructor, in two tranches, with a single assignment between.
#include <stdio.h>
#include <memory>
#include <stdexcept>

class tracer
{
public:
	tracer() { printf("Constructing\n"); }
	~tracer() { printf("Dying\n"); }
};

class tester
{
	std::auto_ptr<tracer> t1_;
	std::auto_ptr<tracer> t2_;
public:
	tester()
	{
		t1_=std::auto_ptr<tracer>(new tracer());
		throw std::runtime_error("Test");
		t2_=std::auto_ptr<tracer>(new tracer());
	}
};

int main()
{
	try
	{
		tester t;
	} catch(const std::runtime_error &ex)
	{
		//Print exception info
	}
	return 0;
}

cyberax@cybmac:~/work$ ./a.out 
Constructing
Dying
And your point is?

Consider that you have to deal with exactly the same crap if you DO NOT use the exceptions. EVERY function you invoke can cause error conditions (such as out-of-memory).

Now please rewrite my example without exceptions, providing the same level of guarantees and functionality.

No thanks.

Posted Nov 10, 2012 23:06 UTC (Sat) by nix (subscriber, #2304) [Link]

You really don't understand, do you?

Consider just these three lines of your example:

t1_=std::auto_ptr<tracer>(new tracer());
throw std::runtime_error("Test");
t2_=std::auto_ptr<tracer>(new tracer());

Let's replace the stupid throw with something more likely to be actually seen in practice, say:

t1_=std::auto_ptr<tracer>(new tracer());
ptr=std::auto_ptr<blah>(new raiied_blah());
t2_=std::auto_ptr<tracer>(new tracer());

Now... if any of those constructors but the first throws, what do you do about it? If, for whatever reason, you cannot use auto_ptr (which is, to be honest, simply pushing off the RAII memory-allocation overhead to something else that has already done all the work) how do you prevent the earlier-allocated ones from leaking? That's right, you have to free at appropriate times in a catch handler. Now figure out which bits can throw. It's hard. It's very, very hard. I recommend Scott Meyers's Effective C++ books for more than you can possibly stomach on this (I wish I could reread mine, but I loaned them out and they never came back, I'm sure you know how it is).

No thanks.

Posted Nov 10, 2012 23:22 UTC (Sat) by Cyberax (✭ supporter ✭, #52523) [Link]

Try it. I really mean it - try it. It would work just fine. Everything will be correctly destroyed.

>If, for whatever reason, you cannot use auto_ptr (which is, to be honest, simply pushing off the RAII memory-allocation overhead to something else that has already done all the work) how do you prevent the earlier-allocated ones from leaking?
By using auto_ptr or any other fitting smart pointer, there's literally no measurable overhead in using it. And there's no excuse in not doing it - and that was clear from the very start. That's actually a rationale for not including the "finally" keyword in C++ - because it might detract from using RAII.

Of course, if you really don't want to do it then you'll have to do the try..catch dance. Exactly like in C where ALMOST EVERY function might result in error and the most common pattern of error handling is "goto err_exit". That's actually why glibc handles OOM by calling abort() - it's simply too complicated to make everything in C error-safe.

PS: I had actually written a simple model verifier to verify my own collection library for upholding exception guarantees. That means that I've obviously read Sutter, Meyers, Stroustroup, Alexandrescu and quite a lot of other C++ writers.

No thanks.

Posted Nov 10, 2012 23:25 UTC (Sat) by foom (subscriber, #14868) [Link]

> Now... if any of those constructors but the first throws, what do you do about it?
You don't have to do anything, because auto_ptr's destructor takes care of it for you.

> If, for whatever reason, you cannot use auto_ptr ( which is, to be honest, simply pushing off the RAII memory-allocation overhead to something else that has already done all the work

That's the whole point! You *always* just use auto_ptr (or another smart pointer, e.g. unique_ptr) to take care of it for you! That's exactly why RAII is so nice, and has been best practice in C++ for years!

No thanks.

Posted Nov 11, 2012 9:32 UTC (Sun) by paulj (subscriber, #341) [Link]

That smart pointers are required exemplifies the "non-trivial" observation made of exception using code. And remind me again, how long have these been available as part of the standard C++ environment?

No thanks.

Posted Nov 11, 2012 10:37 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link]

Since at least 80-s. The problem was mostly in old C programmers who don't know better.

No thanks.

Posted Nov 11, 2012 12:53 UTC (Sun) by paulj (subscriber, #341) [Link]

Rubbish. I have books from the 90s on C++ that fail to mention smart pointers anywhere, written by C++ committee members.

Could good C++ programmers have created their own smart pointers in the 80s? I guess so. My strong impression though is that C++ programmers would have been *way* ahead of the state of understood wisdom in the C++ world at that time. My impression

To claim smart pointers are trivial, widely understood techniques since the 80s stretches credibility somewhat. If they're so trivial, so widely understood for so long, why did it take 20+ years to standardise some? Why is an only relatively recently standardised form of smart pointer already being deprecated in the next C++ standard? (auto_ptr for unique_ptr). My sense is that smart pointers are so trivial that even C++ standards committee members hadn't really fully grokked the implications of copying, moving and sharing them until relatively recently - but I guess they're just "old C programmers who don't know better".

Unfortunately, in the real world, many programmers just aren't quite as brilliant as you.

No thanks.

Posted Nov 11, 2012 13:04 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link]

> Rubbish. I have books from the 90s on C++ that fail to mention smart pointers anywhere, written by C++ committee members.
[citation needed]

> Could good C++ programmers have created their own smart pointers in the 80s? I guess so. My strong impression though is that C++ programmers would have been *way* ahead of the state of understood wisdom in the C++ world at that time. My impression
Well, you'd be wrong. The need for RAII-d resources was understood quite early in the game. I'm not sure about 80-s - there was no significant amount of C++ code then, but surely during the early 90-s.

http://www.stroustrup.com/bs_faq2.html#finally

>If they're so trivial, so widely understood for so long, why did it take 20+ years to standardise some? Why is an only relatively recently standardised form of smart pointer already being deprecated in the next C++ standard? (auto_ptr for unique_ptr).
Mostly for historical reasons. The first C++ Standard was developed in great haste (by ISO standards), there simply was not time to test the proposed things in production. And then it was too late so major additions had to wait until C++11. The same story happened with hash maps, btw.

However, Boost and other libraries had no shortage of various smart pointers.

No thanks.

Posted Nov 11, 2012 14:56 UTC (Sun) by paulj (subscriber, #341) [Link]

Herbert Schildt, "C++ Nuts & Bolts for Experienced Programmers", Osborne McGraw-Hill, 1995. (Yes, Schildt has gotten flack for technical errors / flaws on C++ in his books, and yes, this book wasn't intended to be a reference).

When was Boost created? late 90s. Before Boost there was the HP and SGI STL, which I gather inspired the standardised STL (and Boost?), and iostream. That work dates from the early 90s AFAICT. The SGI STL page doesn't seem to have any kind of smart pointer, dated 1994. C++98 has the auto_ptr, but it apparently is flawed. The early Boost pages reference this: http://web.archive.org/web/19991222182604/http://www.boos... which references books discussing smart pointer programming *patterns* from '92, '94.

I know this stuff is all trivial to you, but it does seem to me that it took about 10 to 15 years (80s to mid/late 90s) for leading C++ programmers to agree on patterns for dealing with exception safety, such as RAII, then getting some kind of smart pointer support in the language (standard or generally available libraries) in order to cope with remaining pitfalls in C++ RAII+exceptions. That smart pointer support then needed further refinement in the mid/late 90s and early 2000s to get to where we are today.

That doesn't quite suggest to me that this stuff is quite as trivial as you suggest to is. Finally, even with smart pointers, I still don't find exception handling code that uses them to be non-trivial! However, you do seem be a superior breed of programmer to the rest of us, so perhaps that's the reason for the discrepancy in views ;). (Intended as a gentle jibe, I hope you'll accept it in that spirit).

No thanks.

Posted Nov 12, 2012 2:05 UTC (Mon) by Cyberax (✭ supporter ✭, #52523) [Link]

>Herbert Schildt, "C++ Nuts & Bolts for Experienced Programmers", Osborne McGraw-Hill, 1995. (Yes, Schildt has gotten flack for technical errors / flaws on C++ in his books, and yes, this book wasn't intended to be a reference).
He's not a member of C++ committee.

>When was Boost created? late 90s. Before Boost there was the HP and SGI STL, which I gather inspired the standardised STL (and Boost?), and iostream.
The STL specification was written before there was a single more-or-less complete STL implementation (and it shows). That was also a problem with lots of C++ features (like exception specification or template export).

Exceptions appeared in GCC 2.7 in 1997, I think. Before that there was little reason to use them and to create best practices for them. Though the usefulness of RAII was understood earlier.

In Java exceptions with try..finally also appeared at about the same time. But without RAII.

No thanks.

Posted Nov 12, 2012 14:35 UTC (Mon) by paulj (subscriber, #341) [Link]

Well, Schildt's wikipedia page says he was involved in C++ standardisation in the 90s. I don't know myself if that's correct or not.

As for exceptions, they were developed in the late 80s, standardised in the early 90s, and there were commercial compilers supporting exceptions since at least '92 apparently. See: http://www.stroustrup.com/hopl2.pdf. The release history of GCC possibly isn't that relevant, a number of proprietary implementations of C++ had more significant usage than g++ back then iirc.

Anyway..

No thanks.

Posted Nov 12, 2012 14:38 UTC (Mon) by paulj (subscriber, #341) [Link]

Oh, the '95 Schildt book has a section on exceptions.


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds