2010-12-08 17 views
7

私たちのコードベースでこのようないくつかのコードにぶつかって...私は心配しました。ローカルスコープからの戻り値?

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

int baz() { 
    int result = { 
     int a = dosomestuff(); 
     foo(a); 
    } ? 0 : -1; 
    return result; 
} 
  1. 明確に定義されたこのコードの動作ですか?
  2. foo(a)の戻り値に応じて、result変数に0または-1がロードされるのは本当ですか?関心を

:コードは、もともとそのように書かれていなかった - しかし、それは私がそれだから、この無実に見えるマクロが

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

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

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

YOW。 Cコンパイラはそれを受け入れますか? gccは確かにしません。 – aschepler

+1

@aschepler:皮肉なことに、GCCはそれを受け入れる*唯一のコンパイラだと思われます!マイケル・バーの答えを見てください。 –

+0

コンパイラはAnalog Devices社のVisualDSP ++です。私はおそらくこの明日のサポートを頼むだろう。 –

答えて

11

これは、CへのGCCの拡張機能であるが、「ステートメント式」と呼ばれる:http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

重要なのは、文の表現が、それは、式の値として行い、最後のものを返すということです。

複合文の最後のものは、式の後にセミコロンを続ける必要があります。この部分式の値は構造全体の値として機能します。

この例では、foo(a)が返されます。

ただし、構文を受け入れるには、GCCのブロックを括弧で囲む必要があります。

int foo(); // Forward declaration. 

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

私はこれをサポートする他のコンパイラには気づきません。

+0

最初にそこに着いた。 FYIはここにGCC Cのすべての拡張モジュールへのリンクがありますhttp://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions –

+4

この具体的なケースでは、それを書くより移植性の高い方法がおそらく順番になる。 'int result = foo(dosomestuff())を考えてみましょう。 0:-1; ' –

+1

@André:間違いなく。ステートメント式のユースケースは、反復する「パラメーターセーフ」マクロまたはマクロを作成するのに役立つようです。私は通常の機能でそれらを使う理由はほとんどないと思う。 –

0

...に展開されます想像するものです非ポインタ単純型の場合、正確な値が返され、戻り動作が定義されます。そのブロックは...本当に奇妙なことですが、私はCコンパイラがそこに詰まることはないと思っています。

1

これを受け入れる単一のコンパイラについてはわかりません。さらに、これをやる方が良いでしょう。

4

コンパイラのドキュメントを参照する必要があります。この構造体は、標準Cまたは標準C++では使用できません。

しかし、これをクリーンアップするのは簡単です(例:

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

はい、私はこの関数をもっと短くすることができます。標準に準拠させるために必要な最小限の変更の例を示しています。この変換は純粋に機械的なので、この構造体を使用するすべてのコードで使用できます。 –

1

標準のC++ではありません。標準C++で

、それだ

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

を書きます。

+0

これは振る舞いを変更します。元の関数は '0'または' -1'を返しますが、boolは '0'と' + 1'です。 –

0

C++ 11あなたはかなり近い取得することができ付:

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

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