From: Thomas Richter on
Louis Lavery wrote:

>> Certainly, that is understood. But assume that the copy constructors of
>> my classes cannot throw (otherwise, of course, I agree that all bets are
>> off, and my code is to blame, and not the STL). However, even then the
>> STL does not ensure that the container is in a state where either all
>> new elements are present, or it remained in the original state. I can
>> certainly arrange that (insert, swap), but without knowing the
>> implementation of insert, not in a way that is as efficient as it could.
>
> I think there are quite efficient ways to do multiple inserts such that
> the container is in a known state should it throw (E.g. a combination of
> splice and range constructors for lists and capacity and reserve for
> vectors). Maybe not as efficiently as the lib's multiple insert, but
> then that's optimised and so doesn't cater for recovery after a throw.
> Exception safety does cost, you know.
>
> It does, of course, require some thought.

Of course. But then, if the "insert" is not "exception safe", isn't that
"optimistic programming" if I cannot recover? It looks to me as "don't
worry about exceptions", whereas whenever I see code outside of the STL,
a lot of arguing goes on that "yes, you should definitely worry". It
seems rather irritating. See also above, I do not expect exception
safety where it is unreasonable. I expect means to recover from
exceptions if I can, and simply more details on such issues.

What you're saying on "optimized insert" sounds to me as, well, "the
algorithm is wrong, but wow, look how fast it is!". Exception-safety and
being able to recover from exceptions is, for me, a central theme in C++.

Greetings,
Thomas

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

From: Thomas Richter on
Mathias Gaunard wrote:

> Then the only reason the container can throw is because it is out of
> memory, which doesn't work reliably on modern operating systems anyway
> due to memory overcommit.

IOW, I cannot use the STL in embedded applications? Or memory
constrained applications? Not everything is a windows or a Linux.
Doesn't that conflict with the design principles of C++?

> Realistically speaking, though, one would expect a good quality
> implementation of insert to allocate all the memory needed beforehand
> when passed a pair or random access iterators, making the primitive
> strongly exception-safe in the lack of user exceptions.

Sure, but why doesn't it then say so? I mean, if you say it is possible
(Francis seems to disagree), then why isn't that documented? It would be
considerably helpful to know that if *my code* cannot throw, the STL
insertion provides a strong guarantee.

So long,
Thomas

--
[ 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 schrieb:

>> 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.
>>
>
> If it was easy to "sanitize", the library would already do that.
>
> The example with a multi-object insert into a vector has the problem
> that the already existing objects will have to be moved around to make
> room for the new ones. If the object type then have a copy constructor
> or a copy assignment that throws, the "move around" can fail.
>
> To restore the original state, you would have to move them back again.
> But that can also fail, if the copy constructor or copy assignment
> throws another exception. Now what do you do?

Let the STL tell me (somehow) which objects have been moved, and which
haven't. In the simplest
possible case, a guarantee the STL could maybe give me would be to say that
of a total of M
objects, if an exception occurs, the first N have been moved, where N is a
number between 0 and M-1.
Now, if the STL would give me a function to access N, I would have a way to
do something about it,
namely either operate on the first N (moved) objects, or the last M-N (not
yet moved) objects to bring
the vector back into some state I can work with. Probably by means that are
available in my specific
implementation, and not in general to the STL.

So long,
Thomas

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

From: Dragan Milenkovic on
On 07/31/2010 04:36 PM, Bo Persson wrote:
> Dragan Milenkovic wrote:
>> On 07/30/2010 08:54 PM, Bo Persson wrote:
[snip]
>>> But they didn't want to do that, just because some type can throw
>>> once in a million years.
>>
>> Sorry, I didn't understand this. I hope you are not describing
>> a class whose ctor can throw only rarely... A type can either
>> throw or it can not; chances and probability must be excluded
>> from the logic. But I'm pretty sure this is not what you meant...
>
> I did actually. :-)
>
> There are classes that can throw, but you might know in advance that
> it isn't going to happen today. If might throw for lack of resources,
> but I know that there are plenty of those resources right now. Then it
> would be safe to use the class anyway.
>
> For an extreme example, say that you have a class that throws an
> exception, but only on February 29th, if it is a Thursday with a lunar
> eclipse. Now I know that today it is around July or August in a year
> that isn't divisible by 4.

Are you perhaps speaking of a std::logic_error kind of exception?
There is no _probability_ involved if you know preconditions
and are certain it will not throw. This is not something to hope for,
but something strictly defined. On the other hand, probability
actually describes something to hope for... There is a difference
in saying "I'm sure there are enough resources" and "There are
most likely enough resources". And IMHO, both of those
are engineering, the first one good kind, the other one bad kind.

You may choose to use an object that would throw once in
a million years, but I would most certainly threat that one
(except if I'm sure that there will be no exception) as if
it could throw at any time.

--
Dragan

[ 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 <i328jv$jji$1(a)speranza.aioe.org>,
Dragan Milenkovic <dragan(a)plusplus.rs> wrote:
>
>Are you perhaps speaking of a std::logic_error kind of exception?
>There is no _probability_ involved if you know preconditions
>and are certain it will not throw. This is not something to hope for,
>but something strictly defined. On the other hand, probability
>actually describes something to hope for... There is a difference
>in saying "I'm sure there are enough resources" and "There are
>most likely enough resources". And IMHO, both of those
>are engineering, the first one good kind, the other one bad kind.

And that is where you have gone wrong. Certainty is something that
is limited to pure mathematics - not even applied mathematics has
it! FAR too many programs have code that relies on assertions like
"I'm sure there are enough resources", and will fail horribly if
that turns out to be false.

Even checking in advance isn't good enough, once you leave artificial
environments, because there are other agents that can deprive you of
resources, asynchronously, by using them for themselves. The minimum
requirement is to check whether there are enough AND RESERVE THEM in
the same operation. And how many non-embedded systems provide THAT
as a primitive?

>You may choose to use an object that would throw once in
>a million years, but I would most certainly threat that one
>(except if I'm sure that there will be no exception) as if
>it could throw at any time.

That is good practice, but it is better to treat ALL actions as if
they might throw at any time. After all, you might run under a
(high-quality) C++ run-time environment that throws an exception
when the system is about to shut down, so that the application can
tidy up and stop.


Regards,
Nick Maclaren.

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