Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385204

Why is g++ allowing me to treat this void-function as anything but?

Why does the following compile in GCC 4.8 (g++)? Isn't it completely ill-formed?

void test(int x)
{
    return test(3);
}

int main() {}
  1. I'm trying to use the result of calling test, which does not exist
  2. I'm trying to return a value from test

Both should be fundamentally impossible — not just UB, as far as I can recall — with a void return type.

The only warning I get is about x being unused, not even anything about a non-standard implicit return type being added.

Live demo

Upvotes: 7

Views: 462

Answers (2)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507055

As to why GCC allows it - sure because the Standard requires it to be valid. Building the transitive closure to the rationale of the rule in the Standard, I'm pretty sure that GCC allows this because it's useful in the event of templates

template<typename F>
typename std::result_of<F()>::type call(F f) {
  return f();
}

int main() {
   std::cout << call([]{ return 42; }) << std::endl;
   call([]{ std::cout << "I'm just an outputtor!" << std::endl; });
}

As you see, call did not need to do a special case for void in the return statement. Sort of similar to how x.~T() is allowed even if T ends up as int.

Upvotes: 6

Mat
Mat

Reputation: 206765

That's allowed by the standard (§6.6.3/3)

A return statement with an expression of type void can be used only in functions with a return type of cv void; the expression is evaluated just before the function returns to its caller.

Upvotes: 10

Related Questions