GotW #102: Exception-Safe Function Calls (Difficulty: 7/10)

JG Question

1. In each of the following statements, what can you say about the order of evaluation of the functions f, g, and h and the expressions expr1 and expr2? Assume that expr1 and expr2 do not contain more function calls.

// Example 1(a)
//
f( expr1, expr2 );

// Example 1(b)
//
f( g( expr1 ), h( expr2 ) );

Guru Questions

2. In your travels through the dusty corners of your company’s code archives, you find the following code fragment:

//  Example 2

//  In some header file:
void f( T1*, T2* );

//  At some call site:
f( new T1, new T2 );

Does this code have any potential exception safety or other problems? Explain.

3. As you continue to root through the archives, you see that someone must not have liked Example 2 because later versions of the files in question were changed as follows:

//  Example 3

//  In some header file:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );

//  At some call site:
f( std::unique_ptr<T1>{ new T1 }, std::unique_ptr<T2>{ new T2 } );

What are the semantics of this call? What improvements does this version offer over Example 2, if any? Do any exception safety problems remain? Explain.

4. Demonstrate how to write a make_unique facility that solves the safety problems in Question 3 and can be invoked as follows:

//  Example 4

//  In some header file:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );

//  At some call site:
f( make_unique<T1>(), make_unique<T2>() );