From: nmm1 on
In article <8b8f2lFbnlU1(a)mid.individual.net>, Bo Persson <bop(a)gmb.dk> wrote:
>Thomas Richter 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.
>
>If it was easy to "sanitize", the library would already do that.

Yes. The decision not to specify it was taken for good reasons;
I may disagree with the choice of objective, but that's another
matter entirely.

>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.

Yes.

>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?

And that is why the design is not easy, and you should NOT specify
the "strong guarantee". What I said what that it could guarantee
to return the vector to a defined state, not what that state was.
Choosing the right definition and specifying it is where the design
effort goes, and is why I said that doing it is comparable effort
to what has already been done.

Actually, I don't see that a multi-object insert is much harder
than a single-object one, as you can implement the former as
repeated applications of the latter. For non-pointer based
containers, ANY insert needs objects moving around.


Regards,
Nick Maclaren.

--
[ 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/29/2010 05:08 PM, Thomas Richter wrote:
> Bo Persson schrieb:
[snip]
>> 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.
[snip]

And how would you handle this situation if further vector operations
could throw?

I already asked in another post... Why would you put in a vector
something that can throw on copy or move? There are other types
of containers that would seem more appropriate. There is also
shared_ptr or at least a pointer (to a well managed object).

Is this an actual real-world problem, or was it just invented
to trash on C++ shortcomings?

--
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 <i2sn4t$dc6$1(a)speranza.aioe.org>,
Dragan Milenkovic <dragan(a)plusplus.rs> wrote:
>On 07/29/2010 05:08 PM, Thomas Richter wrote:
>> Bo Persson schrieb:
>[snip]
>>> 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.
>[snip]
>
>And how would you handle this situation if further vector operations
>could throw?
>
>I already asked in another post... Why would you put in a vector
>something that can throw on copy or move? There are other types
>of containers that would seem more appropriate. There is also
>shared_ptr or at least a pointer (to a well managed object).

The principle of orthogonality means that a container should be
capable of storing any objects that meet its constraints.

>Is this an actual real-world problem, or was it just invented
>to trash on C++ shortcomings?

It's a real-world problem, as everyone who has experience with
that will know. While I accept that C++ (like most similar
languages) doesn't support asynchronous exceptions, the fact is
that they are important and common. For example, signals that
indicate that the system is going down (for an emergency restart
or due to a power cut) are unavoidable, and are critical to
handle in many applications. The killer is that they can occur
in the middle of ANY action.

But, even considering just synchronous exceptions, there are many
objects where exceptions can arise during the invokation of copy
operators and destructors. Consider an object that is a network
connexion - closing one of those can obviously raise an exception.
Similarly, any object with non-trivial memory usage can raise an
exception during a copy.


Regards,
Nick Maclaren.

--
[ 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/30/2010 02:26 AM, nmm1(a)cam.ac.uk wrote:
> In article<i2sn4t$dc6$1(a)speranza.aioe.org>,
> Dragan Milenkovic<dragan(a)plusplus.rs> wrote:
[snip]
>> I already asked in another post... Why would you put in a vector
>> something that can throw on copy or move? There are other types
>> of containers that would seem more appropriate. There is also
>> shared_ptr or at least a pointer (to a well managed object).
>
> The principle of orthogonality means that a container should be
> capable of storing any objects that meet its constraints.

This I agree. I do feel uneasy, like there is a hole in
the specification of std::vector. Me likes things clean
and strictly defined, yes. Maybe, they should have just
banned objects that throw on copy/move.

>> Is this an actual real-world problem, or was it just invented
>> to trash on C++ shortcomings?
>
> It's a real-world problem, as everyone who has experience with
> that will know. While I accept that C++ (like most similar
> languages) doesn't support asynchronous exceptions, the fact is
> that they are important and common. For example, signals that
> indicate that the system is going down (for an emergency restart
> or due to a power cut) are unavoidable, and are critical to
> handle in many applications. The killer is that they can occur
> in the middle of ANY action.
>
> But, even considering just synchronous exceptions, there are many
> objects where exceptions can arise during the invokation of copy
> operators and destructors. Consider an object that is a network
> connexion - closing one of those can obviously raise an exception.
> Similarly, any object with non-trivial memory usage can raise an
> exception during a copy.

But would you put any of those in a vector? How would that work -
would it establish another connection (copy-ctor) and then
close the old one (dtor)? Or would you have a handle
(let's say shared_ptr) to point to that connection?
The same goes for objects with non-trivial memory usage...
do you really want them reallocated all the time?

I know these were just examples, but I would like to see
some real-world examples that _really_ suffer from mentioned
C++ limitations and cannot be overcome unless loosing
_too_much_ on the other side.

--
Dragan

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

From: Bo Persson on
Dragan Milenkovic wrote:
> On 07/30/2010 02:26 AM, nmm1(a)cam.ac.uk wrote:
>> In article<i2sn4t$dc6$1(a)speranza.aioe.org>,
>> Dragan Milenkovic<dragan(a)plusplus.rs> wrote:
> [snip]
>>> I already asked in another post... Why would you put in a vector
>>> something that can throw on copy or move? There are other types
>>> of containers that would seem more appropriate. There is also
>>> shared_ptr or at least a pointer (to a well managed object).
>>
>> The principle of orthogonality means that a container should be
>> capable of storing any objects that meet its constraints.
>
> This I agree. I do feel uneasy, like there is a hole in
> the specification of std::vector. Me likes things clean
> and strictly defined, yes. Maybe, they should have just
> banned objects that throw on copy/move.
>

But they didn't want to do that, just because some type can throw once
in a million years.

It is still allowed to put these objects in a vector, but perhaps you
should avoid multi-object inserts in the middle of the vector, at
times when the risc of an exception is high. :-)

Or perhaps the application can live with the "consistent but unknown
state" of the vector, by discarding it and letting the higher level
operation fail? Youtube video not loading, please try again!


Bo Persson



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