Sunday, May 27, 2012

Named return values in C++11 alternative function syntax declarations

C++11 introduced the ability to specify functions using a different method to the one that's traditional in C and C++03.  This notation is known as alternative function syntax, and involves placing the return type at the end of the function signature rather than at the start.

bool read(int itemIndex); // traditional.
auto read(int itemIndex) -> bool; // alternative function syntax.

Now, what bothers me is why can I not specify the name of the return value using c++11 alternative function syntax? Is that not a major oversight?
The parsing should be trivial, more so than allowing it in standard function syntax.

Here's what I would have liked to have written:

auto multiply(int x, int y) -> int product;
auto read(int itemIndex) -> bool success;


Of course, there's nothing that stops me now just adding this as a comment after the statement:

auto read(int itemIndex) -> bool; // returns success, or not.

But then if you're going to claim that, then you presumably would have been quite comfortable with them not allowing you to specify argument names in traditional declarations.

bool read(int /* the item index */); // returns success, or not.

The above would of course be undesirable, since the declaration gives the caller information as to what is being passed and what is being returned, which goes beyond the types.

So if we added these names to the return value in the declaration, is everything well and good, with no complications?  As it turns out, no, this would indeed raise several issues of its own. 
If you have the notation in the declaration, why not have it in the definition?  You have parameter names in the definition - you have to, if you're going to use them.  So if you supply the name of the return value in the definition, then presumably your function body is going to refer to that name.  Which is fine in a sense, since you have to return something and now you've already got a name for it.
But in that case, how is it defined?  What if the type that you are returning is an object with no default constructor?  Suddenly there are multiple opportunities for the user to have to construct / assign an object to the return value name.  Should they do this the way they would normally, but be forced to select the name that's provided in the function declaration?  If the value was a simple native type, it would be almost sad that you couldn't just write

success = true;
return success;

or even more succinctly, as you do now,

return true;

One solution would be to allow for unnamed return values, as in the second case, which are automatically assigned to the return name (or essentially elided).

Another is to allow the use of a naked return statement in all cases, and require the compiler to detect uninitialised use of the return value.

success = true;
return;

This is starting to seem a little unintuitive, though perhaps it's just because it's deviating a fair bit from previous practice. 

So having the caller see the name of the return value is as useful as seeing the name of the parameters they're supplying, but it may not be a failure in the alternative function syntax given the non-trivial issues that it raises.
I wonder if the issues it raises is why it never made it to the Standard.

No comments:

Post a Comment