views:

180

answers:

5

Consider the following contrived example:

void HandleThat() { ... }

void HandleThis()
{
    if (That) return HandleThat();
    ...
}

This code works just fine, and I'm fairly sure it's spec-valid, but I (perhaps on my own) consider this unusual style, since the call appears to return the result of the function, despite the fact that both functions are prototyped to be void.

Typically, I would expect to see:

if (That) {HandleThat(); return;}

which, I feel, leaves no ambiguity as to what's going on.

SO community, can I get your opinion on whether the returning-void coding style is confusing or problematic? It has the feel of an idiom; should I use this or avoid it?

Generally I'd strive for clarity and use the second style. On the other hand, there's a neatness to the first form that draws me to it somewhat.

+12  A: 

I agree with you, the first style is confusing because there's the implication that some sort of value is getting returned. In fact I had to read it over a couple times because of that.

When returning from a function prototyped void, it should just be return;

Kevin Laity
+1 I can see no good reason why anyone should use the first convention when returning void.
Eric
Agreed, the latter is more intuitive and readable - definitely worth the couple of extra characters.
Amber
The latter is more intuitive and readable. However, the first is also very readable, and what you intuit from it is correct. So it doesn't break your intuition.
Dave Gamble
@Dave: That's true if you consider void to be both a value and a type. I consider it to be a type that cannot contain a value.
Kevin Laity
@Kevin: My instinct tells me that the first convention is slightly misleading. It implied to me that the return of the HandleThat method had some meaning over a simple return statement. I mean this in the context of the first few seconds or milliseconds of looking at it. Based on that I would say the second convention is less likely to cause confusion and is therefore more maintainable. The less time a software engineer has to focus on any one line of code, of the millions he'll(/she'll) have to glance over, the better.
Rich
@Rich: Totally agree
Kevin Laity
+11  A: 

This is probably just a little too clever. If that line ends up more than a couple of lines away from the top of the function, it'll be confusing. It also means the programmer looking at the code will need to correlate the

return HandleThat();

with the void return type and figure out the cleverness before they really understand the code. When you're doing more than one thing in an if/else branch, you should really use braces and put the steps on different lines. Takes up more space but is easier to understand:

if (That) {
    HandleThat();
    return;
}
Harold L
+3  A: 

Never seen that before.

It has the advantage of looking like a common idiom for non-void return types, so it reads very easily...

I wouldn't change it unless someone can show that it is invalid.

dmckee
+4  A: 

The C language rules say if a function declared as returning void tries to return an expression, the expression will not be evaluated.

http://c0x.coding-guidelines.com/6.8.6.4.html

sylvanaar
Both styles generate identical results. For this code: void a() {printf("World!\n");}void b() {printf("Hello, ");return a(); } you get Hello World as expected.
Dave Gamble
I've verified that with full optimisations and stripping using GCC 4.0
Dave Gamble
I think its undefined behavior technically.
sylvanaar
hmm, got a reference for that? As far as I know, it's valid. It's rarely used outside template code, but should be valid and the function does get evaluated. As far as I know, anyway.
jalf
It's well defined and the expression is evaluated. [stmt.return] 'A return statement with an expression of type "cv void" can only be used in functions with a return type of cv void; **the expression is evaluated just before the function returns to its caller** .'
Charles Bailey
Well, it must have been slipped in at some point - that seems to allow it. Though the C standard doesn't have a similar provision http://c0x.coding-guidelines.com/6.8.6.4.html
sylvanaar
I did label the question as C++ specifically.
Dave Gamble
can't be right all the time
sylvanaar
@sylvanaar It's very useful to know that this won't work in C; if you want to edit that in I'll upvote.
Dave Gamble
+2  A: 

I believe that the first version is mainly allowed to ease template programming. If HandleThat returned a type T which might or might not be void, it's convenient to use the first version.

But in "normal" cases, the second version is clearer and I'd prefer that.

jalf