From: Bo Persson on
Michael Kilburn wrote:
> On Jul 18, 3:29 pm, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
> wrote:
>>> I have checked C++ standard and did not find requirements imposed
>>> on library implementation with respect to exception safety.
>>> ...
>>
>> There exist some very general statements and guarantees, see below.
>
> Yes, I saw them... the problem is that quite often they are not
> "very general" -- they are incomplete! I'll quote an example from
> those provided by you:
>
>
>> 5) 23.1/10:
>>
>> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all
>> container types defined in this clause meet the following
>> additional requirements:
>> � if an exception is thrown by an insert() function while
>> inserting a single element, that function has no effects.
>
> ... and what if we are inserting more than one element? what
> effect(s) we are going to have?

Bad probably. :-)

You could also read this as a hint to not insert multiple obejcts at
once, if they are likely to throw exceptions.

As an application programmer, you might know that there are plenty of
resources available so your classes will not throw right now.

>
>
>> � no swap() function throws an exception unless that exception
>> is thrown by the copy constructor or assignment operator of
>> the container�s Compare object (if any; see 23.1.2).[..]"
>
> ... and what is going to happen to the object?

The Compare object is provided by you, the programmer. This rule can
be read as: "If you take care of the Compare object not throwing, the
library guarantees the rest of the container."

It is extremely unusual for compare objects to throw during a swap.
Instead of outright forbidding it, the library instead warns you that
throwing is not good. Perhaps you, as a programmer, can determine if
this particular compare object for this particular container is likely
to throw or not during the next swap.

If it is safe, go ahead and swap the container. If not, perhaps you
can avoid the swap? Or live with the consequences?



Bo Persson



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Thomas Richter on
Bo Persson wrote:

>>> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all
>>> container types defined in this clause meet the following
>>> additional requirements:
>>> � if an exception is thrown by an insert() function while
>>> inserting a single element, that function has no effects.
>> ... and what if we are inserting more than one element? what
>> effect(s) we are going to have?
>
> Bad probably. :-)
>
> You could also read this as a hint to not insert multiple obejcts at
> once, if they are likely to throw exceptions.

This statement looks very irritating to me. What means "likely"? Is
proper programming a matter of probability?

> As an application programmer, you might know that there are plenty of
> resources available so your classes will not throw right now.

??? How should I know how many resources are available? The lack of any
strong guarantee more or less means that proper handling of resource
exhaustion is impossible if you insert more than one element at once.
IOW, all I can do then is to terminate the program? Now, for *that* I
don't need exceptions, do I?

Similar to the OP, I find it very irritating that at one hand education
in C++ stresses proper exception handling and exception safety so much,
while at the other hand the STL provides you with so little to really
*write* exception safe code when using it. That is, code with
*guaranteed* behavior in case of exceptions. Basically, doesn't that
mean that one should stay away from the STL when writing code that can
*truely* handle exceptions correctly, instead of just "hoping the best",
i.e. an optimistic approach as you seem to suggest?

So long,
Thomas


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bo Persson on
Thomas Richter wrote:
> Bo Persson wrote:
>
>>>> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all
>>>> container types defined in this clause meet the following
>>>> additional requirements:
>>>> — if an exception is thrown by an insert() function while
>>>> inserting a single element, that function has no effects.
>>> ... and what if we are inserting more than one element? what
>>> effect(s) we are going to have?
>>
>> Bad probably. :-)
>>
>> You could also read this as a hint to not insert multiple obejcts
>> at once, if they are likely to throw exceptions.
>
> This statement looks very irritating to me. What means "likely"? Is
> proper programming a matter of probability?

Yes, sometimes. :-)

You, as the one writning the possibly throwing copy constructor of a
class, could know when the exception might occur. The library author
cannot.

If you insert 10 small elements into a std::vector, and have 100 GB of
virtual memory available, a std::bad_alloc is not "likely". You can
ask yourself, under what conditions will an exception occur? Do we
have these conditions right now?

Can we run out of memory? Disk space? Network connections? File
handles?

>
>> As an application programmer, you might know that there are plenty
>> of resources available so your classes will not throw right now.
>
> ??? How should I know how many resources are available?

It depends on what resorces the stored objects require. If you write
the classes, you know that but the library author does not.

> The lack of
> any strong guarantee more or less means that proper handling of
> resource exhaustion is impossible if you insert more than one
> element at once. IOW, all I can do then is to terminate the
> program? Now, for *that* I don't need exceptions, do I?

One way to get the strong guarantee is to say that copy constructors
and assignment cannot throw. But that limits the usefulness of the
library.

Another way to get a strong guarantee is to make a copy of the
container, attempt the inserts and, if successful, swap it with the
original. That would be costly, of course, and increase the risk of
getting a bad_alloc.

Still another way is to insert your objects one at a time. That either
works, or not, leaving the contairner in a known state.

>
> Similar to the OP, I find it very irritating that at one hand
> education in C++ stresses proper exception handling and exception
> safety so much, while at the other hand the STL provides you with
> so little to really *write* exception safe code when using it. That
> is, code with
> *guaranteed* behavior in case of exceptions. Basically, doesn't that
> mean that one should stay away from the STL when writing code that
> can *truely* handle exceptions correctly, instead of just "hoping
> the best", i.e. an optimistic approach as you seem to suggest?
>

The library provides you with a lot of tools, but it just cannot help
you with everything for free. If you have a class that throws
exceptions randomly, that isn't very useful.


Bo Persson


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: nmm1 on
In article
<113846b1-5d14-4f3e-8f55-b5f5b9a96fa8(a)5g2000yqz.googlegroups.com>,
Howard Hinnant <howard.hinnant(a)gmail.com> wrote:
>>
>> >Many people don't realize that it is relatively easy to add features
>> >when using a minimal & fast library - making an informed engineering
>> >tradeoff between features and performance. But when given a feature-
>> >rich library (without access to a low-level API), one can't make it
>> >fast when you don't need the features. Doing so is a common mistake
>> >in library design: forgetting or dismissing the importance of the low-
>> >level layer.
>>
>> That is extremely true, but is in flat contradiction to what the
>> OP asked for, and what I understood Dragan Milenkovic to mean.
>>
>> The same is true for RAS, only even more so, and yet more for actual
>> recovery. It is a common and catastrophic mistake to think that
>> either are features, because they are not, and cannot be built on
>> top of a design that doesn't have them. They are fundamental
>> properties of the base design and implementation.
>>
>> There is NO WAY that a programmer can add recovery facilities to
>> the current STL. An implementor can - but, to make it usable, has
>> to specify its properties and constraints - i.e. design an extended
>> STL standard.
>
>After reading your post I got the feeling that I had overlooked a
>proposed design for an extended STL standard in this thread. So I
>reread the thread but somehow am still missing it. I look forward to
>reading a detailed proposal for an extended STL standard.

Please don't be silly. If you had reread the thread, you should
have noticed a posting of mine where I stated that extending the
STL to support recovery from exceptions would be at least as much
design, specification and implementation effort as has been put
into the existing one. As I said, I have practical experience with
similar tasks, and I know what is involved!

If people want to work on such a thing, I am very happy to help (and
even draft proposals as to how), but it is not something that can be
done in one person's spare time. I am not convinced that it is a
good idea, starting from here, anyway - though I don't know C++ well
enough to be sure of that - to a great extent, it depends a lot on
how much of the liberty inherited from C is sacrificable (just as
for garbage collection, only more so).

As an example of what can be specified, consider a container. It is
possible to specify that insertions, deletions etc. are either
nullified or completed, even when interrupted by exceptions caused
by asynchronous signals. That is tricky to implement efficiently,
so another approach is that any container where an operation is
interrupted in some way must be sanitised by calling a special
method before being used again, and then the same applies. And,
similarly, interrupted sorting never loses or duplicates elements,
or adds junk. All of that is known technology, but is in no sense
a trivial extension.

It is even possible to specify that containers are robust against
a limited amount of data corruption - that starts getting extremely
hairy, so I doubt that anyone would want to go there! But it could
be done.


Regards,
Nick Maclaren.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Thomas Richter on
nmm1(a)cam.ac.uk wrote:
>
> As an example of what can be specified, consider a container. It is
> possible to specify that insertions, deletions etc. are either
> nullified or completed, even when interrupted by exceptions caused
> by asynchronous signals. That is tricky to implement efficiently,
> so another approach is that any container where an operation is
> interrupted in some way must be sanitised by calling a special
> method before being used again, and then the same applies. And,
> similarly, interrupted sorting never loses or duplicates elements,
> or adds junk. All of that is known technology, but is in no sense
> a trivial extension.

Let's stick to this example, because it is an excellent one. I don't
think asking for the strong guarantee, i.e. that insertions or deletions
are either done completely or not at all. This is probably asking for
too much. But what I'm asking for is exactly what you mention below,
namely either a method to sanitize the container, or at least *some*
information *how* to sanitize it.

Consider for example an implementation that ensures that on insertion,
the first N of a total of M elements make it into the container; by that
I mean that after an exception, there is an N such that the elements
1,2,.. to N have been inserted and are now members of the container, and
all I would need to do would be to remove them again.

Thus, I would need to find out N after an exception, and the guarantee
that insertions always happens in element increasing order from the
source. Is this asking for too much? As far as I know, the STL doesn't
even give me that.

> It is even possible to specify that containers are robust against
> a limited amount of data corruption - that starts getting extremely
> hairy, so I doubt that anyone would want to go there! But it could
> be done.

Maybe - it would probably require completely different design
principles, and the costs might be high, but I don't really know.
Something simpler would be sufficient.

So long,
Thomas

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]