18

Is the following function safe in C++03 or C++11 or does it exhibit UB?

string const &min(string const &a, string const &b) { return a < b ? a : b; } int main() { cout << min("A", "B"); } 
  • Is it OK to return a reference to an object passed to the function by reference?

  • Is it guaranteed that the temporary string object is not destroyed too soon?

  • Is there any chance that the given function min could exhibit UB (if it does not in the given context)?

  • Is it possible to make an equivalent, but safe function while still avoiding copying or moving?

2
  • Do you need to work with std strings? If you absolutely want to avoid temporaries, you could use std::strcmp(). Commented Apr 29, 2013 at 15:07
  • @bluescarni: It does not matter if there is string or other temporary object type. The question is meant to be general. Commented Apr 29, 2013 at 18:03

5 Answers 5

29

Is it OK to return a reference to an object passed to the function by reference?

As long as the object isn't destroyed before you access it via that reference, yes.

Is it guaranteed that the temporary string object is not destroyed too soon?

In this case, yes. A temporary lasts until the end of the full expression which creates it, so it is not destroyed until after being streamed to cout.

Is there any chance that the given function min could exhibit UB (if it does not in the given context)?

Yes, here is an example:

auto const & r = min("A", "B"); // r is a reference to one of the temporaries cout << r; // Whoops! Both temporaries have been destroyed 

Is it possible to make an equivalent, but safe function while still avoiding copying or moving?

I don't think so; but this function is safe as long as you don't keep hold of a reference to its result.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm certain it's impossible to make an equivalent, because that would require a full GC. You need to track whether there are still references to a temporary object.
The function itself doesn't do anything undefined really (the reference returned will be valid as long as the params are)... its the usage the does IMO
The compiler is allowed to prevent a copy in this case if it's feasible. However, this depends on your compiler and optimization level. GCC, for example, will prevent copying temporary return values with -O2 or greater.
4

Your temporary objects will stay "alive" till the end of the ; from the cout in main, so this way of using it is safe.

Comments

2

Yes, it's safe. The string temps for both "A" and "B" will survive until the end of the 'sequence point', that is the semicolon.

Comments

1

Is it guaranteed that the temporary string object is not destroyed too soon

For your specific case yes, BUT for the following code no

int main() { const string &tempString(min("A", "B")); cout << tempString; } 

Beside that I agree with what "Mike Seymour" said.

2 Comments

It would if there was a const keyword for that temporary reference
Thanks, It's compiling now and does show the case where the problem is.
0

yes it is safe to pass reference through function because in the changes always made in the arguments which you pass by value and in the above code string temps for both A and B will survive until the end of the 'sequence point' that is the semicolon but in case of pass by reference the changes made in copy of that argument not in a original copy.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.