91

Is there a difference between these two statements inside a function?

bool returnValue = true;
// Code that does something
return(returnValue);

and this?

bool returnValue = true;
// Code
return returnValue;

The former has parentheses around returnValue.

Jonas Stein
  • 6,826
  • 7
  • 40
  • 72
Jose Villalta
  • 1,457
  • 1
  • 12
  • 20
  • Thanks Rob, you successfully captured the spirit of the question. In Essence I was wondering whether the compiler did anything special (like trying to evaluate the expression first) or if it just ignored it. – Jose Villalta Jan 23 '11 at 13:26
  • 1
    It is difficult to answer this question for **any** `c++` / `c`. It would be good to be more specific on the language definition, but I do not know how to fix that 9 years later. – Jonas Stein Nov 30 '19 at 15:03
  • For `C` there is a duplicate https://stackoverflow.com/questions/161879/parenthesis-surrounding-return-values – Jonas Stein Nov 30 '19 at 21:33

10 Answers10

145

As of C++14, there is a difference.

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"

tom
  • 21,844
  • 6
  • 43
  • 36
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • The return statement without parenthesis is still an lvalue expression, right? Unless it's being treated as an xvalue in that scenario. Can you explain the value category of the return without parenthesis? – void.pointer Apr 14 '16 at 21:23
  • 1
    The return statement returns a read of the expression fed into it, i.e. it captures an rvalue from the expression it contains and returns that. We never return an lvalue. It may be possible that some compiler has a bug matching the description you give here, and for the reasons you give here, but it should never be the case that `return (x);` is equivalent to `return &x;`, nor should it be possible for it to result in a return of the value of x but with the type reference to x. – Theodore Murdock Nov 03 '16 at 23:55
  • 4
    Wow, what a hideous language construct. Just totally ... opaque. Nice writeup though, thank you. – Paul Sanders Jun 04 '18 at 05:59
  • 8
    C++ is an extremely interesting language. But these kind of hidden "features" drive me nuts sometimes... – andreee Jun 04 '18 at 06:01
  • Our code is full of those unecessary parentheses. We also do use `auto` quite often. **Do our semantics never change as long as we stay away from `decltype`?** I am afraid of unexpected behavior when we move on to the next compiler version that incorporates the next Visual Studio. – OneWorld Dec 03 '18 at 09:54
  • This answer fits even better to https://stackoverflow.com/questions/50674046/why-does-return-str-deduce-a-different-type-than-return-str-in-c where the question is more specific about the language (c++). – Jonas Stein Nov 30 '19 at 15:25
6

There is no difference.

One reason to use parenthesis would be if you wanted to evaluate an expression before returning but in your example, there would be no reason. See:

Parenthesis surrounding return values

for further discussion.

Community
  • 1
  • 1
Karl Rosaen
  • 4,508
  • 2
  • 27
  • 30
  • 3
    Though even with a complicated expression, these parentheses still don't cause a different behavior. They just make the meaning more obvious (subjectively!) to human readers. – aschepler Jan 21 '11 at 19:02
  • @Karl "One reason to use parenthesis would be if you wanted to evaluate an expression before returning" Can you give an example of this? – Chris Middleton Feb 03 '15 at 02:09
  • 3
    @ChrisMiddleton No, because the claim is as nonsensical here as it was in that thread. There is no functional difference whatsoever between `return m * x + c` and `return (m * x + c)` or `return ( (m * x) + c )` or etc. - and it doesn't look any better or more intuitive either, if you ask me. – underscore_d Jul 30 '16 at 23:26
4

AFAIK, nothing is different.

In C++, expressions can have the form: expr or (expr). So, the latter is an expression with more typing. For further reading about this, refer to a grammar (look for "expression").

David Weiser
  • 5,190
  • 4
  • 28
  • 35
  • David, thanks for the link. I have the grammar in Stroustrup's C++ book, but (out of lazyness I guess) don't look at it that much, now that I have it bookmarked in my browser I can refer to it more often. – Jose Villalta Jan 23 '11 at 13:33
4

The parenthesis on the upper example are superfluous; they are effectively ignored.

It would be the same as something like...

int x = (5);

The parenthesis here are ignored as well.

James
  • 5,355
  • 2
  • 18
  • 30
  • Well, technically, they're not *ignored*, they just have no effect on the value of the expression. – John Bode Jan 21 '11 at 19:35
  • 1
    @John: *effectively* ignored. :) – James Jan 21 '11 at 19:40
  • 3
    +1 … this is the only answer that states that the parentheses are actually *redundant* and shows that their usage is a bit stupid. – Konrad Rudolph Jan 21 '11 at 20:23
  • @KonradRudolph: redundant == (bit) stupid? A random example of superfluous parantheses shows that (syntactically) superfluous parentheses are always bad? – DrP3pp3r Oct 17 '22 at 06:24
  • @DrP3pp3r In *this particular case*, yes. I didn't claim that *all* uses of syntactically redundant parentheses are "stupid" (at any rate, I wouldn't use that word today), and I don't know where you got that from. Just to be clear on the semantics, my comment didn't say "redundant = stupid", it said "redundant *and* stupid". – Konrad Rudolph Oct 17 '22 at 07:48
  • @KonradRudolph: I deducted redundant == stupid because redundancy is the only argument against the parentheses in the answer and your comment. Or did I miss something? – DrP3pp3r Oct 17 '22 at 08:04
  • @DrP3pp3r You're missing the code example in the answer, and the (unstated but implied) fact that virtually nobody writes code like this, even people who use parentheses around return values, because it's widely recognised that the parentheses in that example would in fact be extremely silly. Yes, there is a lot of unstated reliance on shared context in the answer and my comment. – Konrad Rudolph Oct 17 '22 at 08:46
  • @KonradRudolph: The example in the answer is exactly the part of the answer I have a problem with. It's just an arbitrary example of superfluous parantheses where basically everyone agrees that that use is silly. But the superfluous parantheses are where the similarity to the return use case ends. And saying "the same as something like" (which is true on the technical level) also implies that the return use case is just as silly. This is like finding one example of a stupid "STOP" sign on a road trying to prove that all "STOP" signs are stupid. – DrP3pp3r Oct 17 '22 at 09:08
  • @DrP3pp3r But the case is very closely (even if not exactly) analogous. I invite you to find the relevant difference that makes parentheses around return values OK. In both cases the parentheses are around a single lexeme without adjacent tokens that might lead to confusion. – Konrad Rudolph Oct 17 '22 at 09:20
  • @KonradRudolph: return like for, if, while, or a function has something like an argument or an expression. The latter ones require you to use parantheses where return does not. An arbitrary choice of the language inventors. No? Also, if x would not be an int but of a class type: x.operator=(5) comes to mind... ;) – DrP3pp3r Oct 17 '22 at 09:45
  • @DrP3pp3r No, not arbitrary at all. `throw`, `sizeof`, `case`, etc. also don't require parentheses. `if`, `for` etc. require them solely to prevent ambiguity with the following expression/block (simplest example to show this: `if (x) +1;` is valid C++, and would be ambiguous without parenthese; that's why all langauges that don't have parentheses around `if` expressions require some token afterwards to disambiguate, e.g. `:`, `then`, `{` etc.). Does this clear it up? – Konrad Rudolph Oct 17 '22 at 09:56
  • @KonradRudolph: It's an arbitrary (purisitcal) choice to say if, while, for do not require { and } if they are followed by a single statement. And thus we need parantheses there. But the better example: A function call does not required parantheses, does it? . It's just arbitrary. It's just because mathematicians do it. Neither do function definitions or declarations. – DrP3pp3r Oct 17 '22 at 10:19
  • @DrP3pp3r How is a function call better? It has the same syntactic limitations as `if`, in that `f(x) + 1` is ambiguous without parentheses. Sure, it's arbitrary that we don't use e.g. Haskell syntax, and you're wrong in fact: C++ syntax does not mirror what mathematicians do, because mathematics generally does *not* use parentheses around the argument of function application ("f *x*" is conventional notation for function application in mathematics). So yes, in the end the choice is arbitrary. But it is *not* arbitrary that `return` (and `throw` and `sizeof`, etc.) is different from `if` etc. – Konrad Rudolph Oct 17 '22 at 11:15
  • @KonradRudolph: It is not ambiguous. It's a question of precendence. Else maths text books that use the form f x would have the same problem, wouldn't they? "mathematics generally does not use parentheses around the argument of function application" is not true. I cannot recall any professor using the form f x in their lectures on the chalkboard or in scripts at my university (HfT Stuttgart, faculty of mathematics). Everyone used f(x). – DrP3pp3r Oct 17 '22 at 11:41
  • @DrP3pp3r Math text books *do* have the same problem (because unfortunately conventions are not universal, which your anecdote illustrates perfectly; although I find it hard to believe that none of your professors wrote e.g. log*x* or sin*x*: parentheses, or even spaces, around the argument are very rare here; if you disbelieve me, just check what typesetting TeX produces by default). Yes, of course ambiguity can be solved: either via precedence rules, or via parentheses. And with that we've come back to the beginning. – Konrad Rudolph Oct 17 '22 at 11:43
  • @DrP3pp3r And to reinforce this point, a lot of mathematicians use redundant parentheses specifically to combat the ambiguity inherent in the lack of a universal convention, and to increase readability. Which is why it is entirely natural for C++ to adopt parentheses around expressions that otherwise introduce potential ambiguity. This is the case for `if` etc. but not for `return` etc. – Konrad Rudolph Oct 17 '22 at 11:50
  • @KonradRudolph You're correct about sin x, log x, and the like. That was ofc used. I was caught up too much in the context of abstract function names like f(x) or g(x, y). – DrP3pp3r Oct 17 '22 at 11:55
  • @DrP3pp3r ... why did your professors use different notation for specific functions than for other functions? This certainly isn't unheard of, but you must admit that it's inconsistent, and maybe not a great reference point for the design of a programming language ... – Konrad Rudolph Oct 17 '22 at 11:57
  • @KonradRudolph: Because h x sin x is hard to read on a chalkboard, And you have to know h is a function. h(x)sin x is much clearer. But this is getting OT now. – DrP3pp3r Oct 17 '22 at 12:15
3

No, there are no difference in your code.

Elalfer
  • 5,312
  • 20
  • 25
1

No difference!!

People use parenthesis if there's a complex expression involved.

BTW return is a statement not a function.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
1

Nope there's no difference between the two, although you can include parenthesis if it makes the expression easy to read and clear.

sanchit.h
  • 134
  • 10
  • 1
    ...but it never does. Why would it? What's difficult to read about an unparenthesised expression? Adding parentheses just looks like clutter to me. As for seeming clearer, do people think `return` is a greedy operator and that `return m * x + c` might return `m` and discard the rest, or what? – underscore_d Jul 30 '16 at 23:30
1

You're abusively slowing down the compiler!

The presence of parenthesis not only slow down the preprocessing phase, but they generate a more complicated Abstract Syntax Tree too: more memory, more computation.


From a semantic point of view ? They are exactly identical. Whether there are parenthesis or not the return statement will fully evaluate the expression before returning it.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 5
    My thinking exactly. By making the compiler do unnecessary work parsing useless clutter it is nearing the heat death of the universe for no good reason. – Maxim Egorushkin Jan 21 '11 at 20:42
  • How much of a difference does that seriously make? Even over a large code base? Is that a good guideline for writing code? Making life for the compiler easier? And we're talking about hyper-micro-optimizations here, not about a huge impact in compile time that is noticeable by a human. Are curly braces used with ifs or loops bad too if those only contain one statement? Maybe we shouldn't use comments in code either. Pointless work for the compiler. Functions and variables should only have one-character names, too. Faster to process. Right? – DrP3pp3r Oct 14 '22 at 07:36
  • IMHO primarily the code should be easy to understand. Not optimized. Neither for compile-time nor run-time. – DrP3pp3r Oct 14 '22 at 07:36
  • @DrP3pp3r: This answer is _obviously_ sarcastic. Given how many MBs of header the preprocessor pulls in, a few hundred more parentheses will be meaningless performance wise. With that said, I encourage writing for readability, and that means avoiding needless clutter -- there is no point in having parentheses around the expression passed to the return statement. – Matthieu M. Oct 14 '22 at 12:56
  • @MatthieuM.: Didn't catch the sarcasm, my bad. Parentheses around function arguments (maths functions got them, so we got them here, I guess), after ifs, fors, and while are not necessary either, still the language inventors chose to put them there). Are they clutter? Also, readability might be quite a subjective thing here. Maybe where you see clutter others see order. Maybe let's go with Alexandrescu: "Don't sweat the small stuff." – DrP3pp3r Oct 17 '22 at 05:47
  • @DrP3pp3r: Actually, in Rust, there's no parenthesis round in `if`, `for`, or `while`, and they're not missed. Parentheses around functions arguments are more difficult to get rid of: should `f 3 + 4` be parsed as `f(3) + 4` or `f(3 + 4)`? Precedence can be used, but precedence rules can quickly become confusing. – Matthieu M. Oct 17 '22 at 07:01
0

They are identical. I see the parenthesis syntax quite often, and I always ask those who use it: why? And none can answer why they use it.

To bluntly sum it up, parenthesis around returning expressions are used by people who don't quite grasp the difference between function-like macros and functions, or who are confused about the operator precedence or order of evaluation rules in C. There is no coding style benefit from using parenthesis.

Thus

return value;

is more correct than

return (value)

because the latter suggests you don't quite know what you are doing :)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • "Why?" Maybe for some sort of consistency. If, while, for are no functions either but parantheses are necessary there. – DrP3pp3r Oct 14 '22 at 07:12
  • @DrP3pp3r `return` is a jump statement, not a selection or iteration statement. So it should be compared to `goto`, `break` and `continue` rather than anything else. Do you use parenthesis whenever you use `goto`, `break` or `continue`? If so, how did you even manage that syntax-wise? – Lundin Oct 14 '22 at 12:59
  • I disagree with your comparison argument. As return technically/syntactically is a jump statement, it has a similarity with functions, ifs, whiles, and fors: It takes some argument(s))/expression(s). break and continue don't. goto does, but doesn't allow parentheses. Arbitrary design choice of the language inventors? You don't _need_ them there? Neither do you with functions, ifs, whiles, and fors. Starting with the 2nd sentence your answer becomes opinion-based IMHO. – DrP3pp3r Oct 17 '22 at 06:15
  • @DrP3pp3r First of all, this answer is ancient, from a different time with different standards regarding what's off-topic. "Neither do you with functions, ifs, whiles, and fors." err yes, you do. Now if you wish to compare `return` and `if`, the formal syntax for `return` is: `return` _expression_ `;`. The formal syntax for `if` is `if (` _expression_ `)`. Like it or not, that's how the language was designed. `if` _requires_ parenthesis by the formal syntax definition. – Lundin Oct 17 '22 at 06:28
  • I think you misunderstood me. Yes, ofc with the way the syntax _is_ you need parentheses with if, for, while. But it was not necessary to _define_ the syntax this way. There are enough languages that showcase that. It was a choice of the language creators of C to do it this way. And for return, they decided differently. Not all their choices were great. And yes, there's the technical definition and there's the human perspective. Code is for humans to read and write. You like it puristical others don't. – DrP3pp3r Oct 17 '22 at 07:59
-3

Both are the same in your case.

Zeshan Khan
  • 294
  • 2
  • 15
  • M.M could you please explain your comment? – Zeshan Khan Oct 26 '15 at 14:17
  • 1
    if `a` is `5` then `return a++;` and `return (a++);` (which is the same) will both return `5` – M.M Oct 26 '15 at 19:47
  • 2
    specificaly, postinc/decrement returns the pre-modification value of its operand, and no amount of parentheses or other fruitless attempts at coercion will change that. – underscore_d Jul 30 '16 at 23:46