The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

Gulzt (3) [Avatar] Offline
#1
I don't understand the following text:

Option 3: Return a pointer to the popped item

The third option is to return a pointer to the popped item rather than return the item by value. The advantage here is that pointers can be freely copied without throwing an exception, so you’ve avoided Cargill’s exception problem.


I don't understand why the use of pointers by itself avoids Cargill's exception problem. Isn't your option 1 also avoiding Cargill's exception problem?

If
std::shared_ptr const res(std::make_shared<T>(data.top()));

throws an exception, then data.pop() is not executed.

If in option 1,
value = data.top()
, throws an exception, then data.pop() isn't executed either.

I see the benefits of option 3, but I don't understand how it relates to Cargill's exception problem.

Could you clarify?
Madhusudhan Srikkanth (7) [Avatar] Offline
#2
For the example you have suggested, the function that takes an argument by reference and also the function that returns a shared_ptr both provide exception safety guarantees. I am assuming that you already know why returning a shared_ptr is exception safe. Copying a shared_ptr is guaranteed not to throw an exception unlike when you call a user defined copy constructor or assignment operator. For this example (3.2.3) you just require one of these functions.

To understand why Anthony Williams mentions returning a shared_ptr as an alternative to taking a parameter by reference will be clear when you read Chapter 7. In particular read the section on implementing pop method for a lockfree_stack.

I am quoting from the book below:

The second problem is an exception-safety issue. When we first introduced the thread-safe
stack back in chapter 3, you saw how just returning the object by value left you with an
exception safety issue: if an exception is thrown when copying the return value, the value is
lost. In that case, passing in a reference to the result was an acceptable solution because you
could ensure that the stack was left unchanged if an exception was thrown. Unfortunately,
here you don’t have that luxury; you can only safely copy the data once you know you’re the
only thread returning the node, which means the node has already been removed from the
queue. Consequently, passing in the target for the return value by reference is no longer an
advantage: you might as well just return by value. If you want to return the value safely, you
have to use the other option from chapter 3: return a (smart) pointer to the data value.
Gulzt (3) [Avatar] Offline
#3
Oh I see, thanks for clarifying.