Is std::exception_ptr movable?

350 views
Skip to first unread message

Vicente J. Botet Escriba

unread,
Apr 4, 2013, 1:51:06 AM4/4/13
to std-dis...@isocpp.org
Hi,

is std::exception_ptr movable? If yes, what is the state of a
std::exception_ptr after been moved?

Could you point me to the standard where it is described?

Best,
Vicente

Daniel Krügler

unread,
Apr 4, 2013, 2:19:01 AM4/4/13
to std-dis...@isocpp.org

2013/4/4 Vicente J. Botet Escriba <vicent...@wanadoo.fr>

Hi,

is std::exception_ptr movable?

What do you precisely mean with "movable"? According to [propagation] p2 std::exception_ptr satisfies the NullablePointer requirements, which again ensures that it satisfies the CopyConstructible requirements. By implication (see Table 21 — CopyConstructible requirements), it also satisfies the MoveConstructible requirements.

Among other things it means that the initialization of b in

std::exception_ptr a = ...;
std::exception_ptr b = std::move(a);

shall be well-formed.
 
If yes, what is the state of a std::exception_ptr after been moved?

This should fall under the general statements of Table 20 — MoveConstructible requirements [moveconstructible]:

"rv’s state is unspecified [ Note:rv must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether rv has been moved from or not. —end note ]"

But there exists one additional constraint implied by [propagation] p7:

"For purposes of determining the presence of a data race, operations on exception_ptr objects shall access and modify only the exception_ptr objects themselves and not the exceptions they refer to. [..]"

One possible way is that an implementation provides a move constructor that causes the source std::exception_ptr object to be produce a null value. But it is not be allowed to modify the contained exception object (if there is one).
 
Could you point me to the standard where it is described?

See above.

- Daniel

Vicente J. Botet Escriba

unread,
Apr 4, 2013, 2:37:44 AM4/4/13
to std-dis...@isocpp.org
Le 04/04/13 08:19, Daniel Kr�gler a �crit�:

2013/4/4 Vicente J. Botet Escriba <vicent...@wanadoo.fr>
Hi,

is std::exception_ptr movable?

What do you precisely mean with "movable"? According to [propagation] p2 std::exception_ptr satisfies the NullablePointer requirements, which again ensures that it satisfies the CopyConstructible requirements. By implication (see Table 21 � CopyConstructible requirements), it also satisfies the MoveConstructible requirements.

Among other things it means that the initialization of b in

std::exception_ptr a = ...;
std::exception_ptr b = std::move(a);

shall be well-formed.
�
If yes, what is the state of a std::exception_ptr after been moved?

This should fall under the general statements of Table 20 � MoveConstructible requirements [moveconstructible]:

"rv�s state is unspecified [ Note:rv must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether rv has been moved from or not. �end note ]"

But there exists one additional constraint implied by [propagation] p7:

"For purposes of determining the presence of a data race, operations on exception_ptr objects shall access and modify only the exception_ptr objects themselves and not the exceptions they refer to. [..]"

Thanks for all the pointers.
One possible way is that an implementation provides a move constructor that causes the source std::exception_ptr object to be produce a null value. But it is not be allowed to modify the contained exception object (if there is one).
�

Are you saying that this is� mandatory that an implementation update the source exception_ptr to a null value? That is, does the standard requires the following?


std::exception_ptr a = ...;
std::exception_ptr b = std::move(a);
assert(a == std::exception_ptr());

Vicente

Anthony Williams

unread,
Apr 4, 2013, 3:15:13 AM4/4/13
to std-dis...@isocpp.org
On 04/04/13 07:37, Vicente J. Botet Escriba wrote:
> Le 04/04/13 08:19, Daniel Kr�gler a �crit :
>> One possible way is that an implementation provides a move constructor
>> that causes the source std::exception_ptr object to be produce a null
>> value. But it is not be allowed to modify the contained exception
>> object (if there is one).
>>
>
> Are you saying that this is mandatory that an implementation update the
> source exception_ptr to a null value? That is, does the standard
> requires the following?
>
> std::exception_ptr a = ...;
> std::exception_ptr b = std::move(a);
> assert(a == std::exception_ptr());

No. "a" may be a null value, or may be equal to "b", or may be another
valid value. The "obvious" implementations are that move==copy or move=>
null source, but there are no restrictions on the value of "a" except
that it is a valid exception_ptr.

Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++11 thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Daniel Krügler

unread,
Apr 4, 2013, 3:15:42 AM4/4/13
to std-dis...@isocpp.org
2013/4/4 Vicente J. Botet Escriba <vicent...@wanadoo.fr>
Le 04/04/13 08:19, Daniel Krügler a écrit :

One possible way is that an implementation provides a move constructor that causes the source std::exception_ptr object to be produce a null value. But it is not be allowed to modify the contained exception object (if there is one).
 

Are you saying that this is  mandatory that an implementation update the source exception_ptr to a null value?

No.
 
That is, does the standard requires the following?

std::exception_ptr a = ...;
std::exception_ptr b = std::move(a);
assert(a == std::exception_ptr());

It doesn't. There is no requirement that std::exception_ptr does have a move constructor at all.

- Daniel

Vicente J. Botet Escriba

unread,
Apr 4, 2013, 1:26:16 PM4/4/13
to std-dis...@isocpp.org
Le 04/04/13 09:15, Daniel Krügler a écrit :
Ok. Was this intentional? what was the rationale?

Daniel Krügler

unread,
Apr 4, 2013, 4:46:58 PM4/4/13
to std-dis...@isocpp.org
I'm currently unaware whether this was explicitly discussed. I guess it was not. On the other side: I'm currently also unaware where this guarantee would be very important, since *by default* the state of moved-from objects is unspecified. Could you point out where the guarantee of an null value source of a move would be important for std::exception_ptr?

- Daniel
 

Vicente J. Botet Escriba

unread,
Apr 7, 2013, 3:16:15 PM4/7/13
to std-dis...@isocpp.org
Le 04/04/13 22:46, Daniel Krügler a écrit :
While testing an expected<T> implementation I was expecting that the source of a move will not have an exception associated, but for what you say, I should be wrong, an the expected state should be undefined.

Best,
Vicente

Daniel Krügler

unread,
Apr 7, 2013, 3:40:04 PM4/7/13
to std-dis...@isocpp.org
2013/4/7 Vicente J. Botet Escriba <vicent...@wanadoo.fr>:
> Le 04/04/13 22:46, Daniel Krügler a écrit :
>
[..]
> While testing an expected<T> implementation I was expecting that the source
> of a move will not have an exception associated, but for what you say, I
> should be wrong, an the expected state should be undefined.

More precisely, for std::exception_ptr the state of the source of a
move is unspecified. You should be able to call every member function
that has a wide contract (i.e. that has no precondition of calling
it). I wonder why you find the precise state of a source of a move
important, since it actually is an object that you should have given
up interest in.

Note that the standard library has already wording special wording in
[res.on.arguments] p1 b3,

"If a function argument binds to an rvalue reference parameter, the
implementation may assume that this parameter is a unique reference to
this argument. [ Note: If the parameter is a generic parameter of the
form T&& and an lvalue of type A is bound, the argument binds to an
lvalue reference (14.8.2.1) and thus is not covered by the previous
sentence. —end note ] [ Note: If a program casts an lvalue to an
xvalue while passing that lvalue to a library function (e.g. by
calling the function with the argument move(x)), the program is
effectively asking that function to treat that lvalue as a temporary.
The implementation is free to optimize away aliasing checks which
might be needed if the argument was an lvalue. —end note ]"

that gives implementations special allowance for moveable objects.

Let me make clear, that I'm not strongly against adding more concrete
move semantics of std::exception_ptr to the library specification, I'm
only wondering how important that would be.

- Daniel
Reply all
Reply to author
Forward
0 new messages