Are Parentheses Around the Result Significant in a Return Statement

Are parentheses around the result significant in a return statement?

As of C++14, they often are.

C++14 adds a fringe case where parentheses around a return value may alter the semantics. This code snippet shows two functions being declared. The only difference is parentheses around the return value.

int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))

In the first func1 returns an int and in the second one func1 returns an int& . The difference in semantics is directly related to the surrounding parentheses.

The auto specifier in its latest form was introduced in C++11. In the C++ Language Spec it is described as:

Specifies that the type of the variable that is being declared will be automatically
deduced from its initializer. For functions, specifies that the return type is a trailing
return type or will be deduced from its return statements (since C++14)

As well C++11 introduced the decltype specifier which is described in the C++ Language Spec:

Inspects the declared type of an entity or queries the return type of an expression.

[snip]

  1. If the argument is either the unparenthesised name of an object/function, or is a member access expression (object.member or pointer->member), then the decltype specifies the declared type of the entity specified by this expression.

  2. If the argument is any other expression of type T, then

    a) if the value category of expression is xvalue, then the decltype specifies T&&

    b) if the value category of expression is lvalue, then the decltype specifies T&

    c) otherwise, decltype specifies T


[snip]

Note that if the name of an object is parenthesised, it becomes an lvalue expression, thus decltype(arg) and decltype((arg)) are often different types.

In C++14 the ability to use decltype(auto) was allowed for function return types. The original examples are where the semantic difference with parentheses comes into play. Revisiting the original examples:

int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))

decltype(auto) allows the trailing return type in the function to be deduced from the entity/expression on the return statement. In the first version return var1; is effectively the same as returning the type decltype(var1) (an int return type by rule 1 above) and in the second case return (var1); it's effectively the same as decltype((var1)) (an int & return type by rule 2b).

The parentheses make the return type int& instead of int, thus a change in semantics. Moral of the story - "Not all parentheses on a return type are created equal"

Parenthesis surrounding return values in C

There really isn't a reason...it's just old convention.

To save space, programmers would often do the final math in the return line instead of on it's own line and the parens ensure are mostly there to make it easier to see that it is a single statement that is returned, like this:

return (x+i*2);

instead of

int y = x+i*2;
return y;

The parenthesis became a habit and it stuck.

Parentheses around return values - why?

With respect to C

Parentheses are put where there is an expression and one wants the return value to be that value of the expression. Even then parentheses are not needed. It is completely ok to write something like

return x + y;

Programmers do make it return (x + y); to make it more readable.

So, putting parentheses is a matter of opinion and practice.


With respect to C++

There is an arcane case where parentheses matters. Quoting this question

int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))

You can see the returned values are different, and that is due to the parentheses. You can go through this answer to understand in detail.


With respect to java, parentheses does not make any difference.

Coding convention suggests to go with

return x + y;

to understand more, read this answer.


NOTE: I do not know much about java and C++. All of the content in my answer about java and C++ are taken from other answers. I did this to consolidate the different conventions for the three languages.

Should a return statement have parentheses?

There are generally 4 uses for the parentheses () in Python.

  1. It acts the same way as most of the other mainstream languages - it's a construct to force an evaluation precedence, like in a math formula. Which also means it's only used when it is necessary, like when you need to make sure additions and subtractions happen first before multiplications and divisions.
  2. It is a construct to group immutable values together in the same spirit as a similar set notation in math. We call this a tuple in Python. Tuple is also a basic type. It is a construct to make an empty tuple and force operator precedence elevation.
  3. It is used to group imported names together in import statements so you don't have to use the multi-line delimiter \. This is mostly stylistic.
  4. In long statements like


decision = (is_female and under_30 and single
or
is_male and above_35 and single)

the parenthesis is an alternative syntax to avoid hitting the 80 column limit and having to use \ for statement continuation.

In any other cases, such as inside the if, while, for predicates and the return statement I'd strongly recommend not using () unless necessary or aid readability (defined by the 4 points above). One way to get this point across is that in math, (1) and just 1 means exactly the same thing. The same holds true in Python.

People coming from the C-family of languages will take a little bit getting used to this because the () are required in control-flow predicates in those languages for historical reasons.

Last word for return statements, if you are only returning 1 value, omit the (). But if you are returning multiple values, it's OK to use () because now you are returning a grouping, and the () enforces that visually. This last point is however stylistic and subject to preference. Remember that the return keywords returns the result of a statement. So if you only use , in your multiple assignment statements and tuple constructions, omit the (), but if you use () for value unpacking and tuple constructions, use () when you are returning multiple values in return. Keep it consistent.

Returning by reference. Parentheses around a return variable

A image can say thousands of words

A image can explain more than thousands of words. I think both are correct you and documentation also. You should see version first because during coding we have to keep in mind that which version we are using.

Why use parentheses when returning in JavaScript?

It doesn't need to be that way, but it's valid JavaScript code. Actually it's quite uncommon to see such syntax. I guess it's a personal preference of the author.

Why is the parentheses at end of return statement used in code below and why does if I don'y use parentheses it return address?

Try splitting such one-liners on some meaningful parts.

def dictuse1(operator, x, y):
# Stores mapping from operator names (strings)
# to op implementations (functions == lambdas)
optable = {
'add': lambda: x + y,
'sub': lambda: x - y,
'mul': lambda: x * y,
'div': lambda: x / y,
}

# Define a default op
noop = lambda: None

# Take the function by op name
op = optable.get(operator, noop)

# Exectute it and return a returning value of that function.
return op() # remove () and you have a dictuse2 here.

The only difference between dictuse1 and dictuse2 that the last one returns the function instead of the result of the invocation of that function.

Why can I omit the return statement with parenthesis in React

The first snippet is implicit return. Parentheses are provided only for developer's convenience; it's possible to unambiguously parse the code without them, at the expense of readability:

const Nav = () =>
<nav className="c_navbar">
{ some jsx magic here }
</nav>

While the second snippet contains explicit return. This is the case when parentheses are commonly used in React, because when there's no optional expression right after return statement, there is no returned value.

  return
<nav className="c_navbar">
{ some jsx magic here }
</nav>

is parsed as

  return;
<nav className="c_navbar">
{ some jsx magic here }
</nav>

In order to be parsed correctly without parentheses, it should be:

  return <nav className="c_navbar">
{ some jsx magic here }
</nav>

So parentheses are commonly used for consistency in both implicit and explicit returns and allow to improve the readability with proper indentation.



Related Topics



Leave a reply



Submit