Cryptography Man
Cryptography Man

Reputation: 209

Void function doing return (void)(something)

I saw a few functions in an SDK I'm using do something similar to the following:

void foo( float& fl )
{
    if ( std::isnan( fl ) || std::isinf( fl ) )
        return ( void )( fl = 0.f );
    /*...*/
}

Why?

Upvotes: 3

Views: 159

Answers (3)

Why?

On the face of it, someone was just being "clever". You see, there are restrictions placed on a return statement in C++

[stmt.return]

2 The expr-or-braced-init-list of a return statement is called its operand. A return statement with no operand shall be used only in a function whose return type is cv void, a constructor, or a destructor. A return statement with an operand of type void shall be used only in a function whose return type is cv void. A return statement with any other operand shall be used only in a function whose return type is not cv void; [...]

The above makes a simple return ( fl = 0.f ); in that function illegal. Because the expression ( fl = 0.f ) (the return statement's operand) is not of type void. But the author of that function, maybe in an effort to conserve lines of code, or to express some sort of "elegance", decided to force the issue. Since an operand of type void is okay, they added a cast. That's not the only way to make the compiler submit, for instance:

return fl = 0.f , void();

That makes use of the comma operator, and the void() prvalue. It's not code I'd personally advocate one to write. The code in your post and this alternative are unidiomatic, confusing and misguided. Braces ({}) would have made that function much clearer. So while I hope you learned something about C++ from this, don't get in the habit of writing such code. Your colleagues will think more highly of you if you write code they can understand at a glance.

Upvotes: 3

Jeremy Friesner
Jeremy Friesner

Reputation: 73041

    return ( void )( fl = 0.f );

Why?

That is rather unusual code. Casting an expression to void is usually done to suppress a compiler-warning -- it's an idiom that tells the compiler "yes, I know I am throwing this expression's value away -- but I'm doing it deliberately, so you don't need to warn me about it".

What is unusual there is that the author decided to do that in a return statement. It would have been clearer (and logically equivalent) to write

{
   fl = 0.0f;
   return;
}

instead. The only thing I can think of is that the function used to return a value, and perhaps the author thought he might someday want to change it to return a value again, and would therefore try to keep the code-style looking similar to that of a value-returning function? (If so, it seems a bit "too clever" to me)

Upvotes: 1

apple apple
apple apple

Reputation: 10591

It's the same as

void foo( float& fl )
{
    if ( std::isnan( fl ) || std::isinf( fl ) )
    {
        fl = 0.f;
        return;
    }
    /*...*/
}

there is no special reason to prefer one way than another.

Upvotes: -1

Related Questions