44

Linuxカーネルソースを閲覧すると、括弧で囲まれたステートメントのブロックが式a la lisp(またはML)、つまり最後のステートメントの値である式として扱われるコードが見つかりました。

例えば:

int a = ({
    int i;
    int t = 1;
    for (i = 2; i<5; i++) {
        t*=i;
    }
    t;
});

このコードが解析ツリーにどのように適合するかを理解しようとしてANSIC文法を調べてきましたが、成功していません。

それで、この振る舞いが標準によって義務付けられているのか、それとも単にGCCの特性なのかを誰かが知っていますか?

更新:フラグ-pedanticを試してみましたが、コンパイラーから警告が表示されるようになりました。

warning: ISO C forbids braced-groups within expressions
4

2 に答える 2

42

これは標準 C ではありません。ステートメント式と呼ばれる gcc 拡張機能です。C 拡張機能の完全なリストは、ここにあります。これは実際には Linux カーネルで使用される多くの gcc 拡張機能の 1 つであり、 clang もこれをサポートしているようですが、ドキュメントでは明示的に名前が付けられていません。

最後の式が式の値として機能することを観察したように、ドキュメントには次のように記載されています(強調鉱山):

複合ステートメントの最後の部分は、式の後にセミコロンを付ける必要があります。この部分式の値は、構造全体の値として機能します。(中かっこ内で他の種類のステートメントを最後に使用する場合、構造は void 型を持つため、実質的に値はありません。)

主な利点の 1 つは、副作用のある引数の複数回の評価を回避する安全なマクロを作成することです。この例では、次の安全でないマクロを使用しています。

#define max(a,b) ((a) > (b) ? (a) : (b))

aこれはどちらかまたは2 回評価さbれ、次のようにステートメント式を使用してこの問題を解消するために書き直すことができます。

#define maxint(a,b) \
   ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) 

int別のgcc拡張Typeofを使用して修正できる whichを明示的に使用する必要があることに注意してください。

#define max(a,b) \
   ({ typeof (a) _a = (a), _b = (b); _a > _b ? _a : _b; }) 

clang は typeof もサポートしていることに注意してください。

于 2013-09-19T03:11:26.613 に答える
38

これは「式内の波括弧グループ」と呼ばれます。

ANSI/ISO C や C++ では許可されていませんが、gcc ではサポートされています。

于 2009-08-06T10:15:33.180 に答える