开发者

Return value from local scope?

Bumped into some code like this in our code base... which made me worried.

int foo(int a); // Forward declaration.

int baz() {
    int result = {
         int a = dosomest开发者_如何学运维uff();
         foo(a);
    } ? 0 : -1;
    return result;
}
  1. Is the behavior of this code well-defined?
  2. Will it really work, that result variable gets loaded with 0 or -1 depending on the return value of foo(a)?

For interest: The code was not written like that originally - however, it is what I imagine this innocent-looking macro will roll out to...

int foo(int a); // Forward declaration.

#define BAR()  { int a = dosomestuff(); foo(a); }

int baz() {
    int result = BAR() ? 0 : -1;
    return result;
}


This is a GCC extension to C called 'statement expressions': http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

The key thing is that a statement expression returns the last thing it does as the value of the expression:

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct.

In your example, that would be whatever foo(a) returns.

However the block must be enclosed in parens for GCC to accept the syntax.

int foo(); // Forward declaration.

int baz() {
    int result = ({
         int a = dosomestuff();
         foo(a);
    }) ? 0 : -1;
    return result;
}

I'm unaware of any other compiler that supports this.


You'd have to consult your compiler documentation. This construct is not allowed in standard C or standard C++.

It's trivial to clean this up however, e.g.

int baz()
{
    int result;
    {
         int a = dosomestuff();
         result = foo(a)? 0: -1;
    }
    return result;
}


I do not know of a single compiler that will accept that. Additionally, you'd be better off doing this:

int foo();
int dosomestuff();

int baz()
{
   int result = foo(dosomestuff()) ? 0 : -1;
   return result;
}


It's not standard C++.

In standard C++, write

bool baz() { return !foo( dosomestuff() ); }

That's it.


Because it's a non-pointer simple type, the exact value will be returned and so the return behavior is defined. That block is... really strange though, and I'm surprised there's a C compiler that won't choke on it out there.


With C++11 you can get pretty close:

int foo(int a); // Forward declaration.

int baz() {
    int result = []{
         int a = dosomestuff();
         return foo(a);
    }() ? 0 : -1;
    return result;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜