2016-08-04 3 views
-4

は、私はこのように動作しますイテレータのマクロを定義したい:このコードは有効ですか?互換性の理由から

elem_type *ptr; 
ITERATE(&container, ptr) { 
    // This will loop through every element of the container 
    // ptr will point to the current element. 
} 

私は関数呼び出しで初期化する必要がありますイテレータ型を持っており、このように動作します:

iter_type iter; 
iter_init(&container, &iter); 
while((ptr = iter_next(&iter))) { 
    // ... 
} 

だから、これは私がマクロにこのシーケンスを圧迫する思い付いたソリューションです:あなたが見ることができるよう、

#define ITERATE(container_ptr,elem_ptr) \ 
    for(iter_type _iter = (\ 
     iter_init(container_ptr, &_iter), _iter); \ 
     (elem_ptr = iter_next(&_iterator));) 

そうで、ちょっとしたトリックワットがありますコンマ演算子を使用して、forの最初のコロンに変数宣言と関数呼び出しの初期化の両方を適合させます。このコードは有効なC99ですか、常に動作しますか?

+4

有効ですか?有効なものを定義する。コンパイルは最初のステップかもしれません。また、あなたはこのマクロを発明する最初の人ではありません。その共通のものです。 - Linuxカーネルを確認してください。 –

+0

私の有効な定義は "とっても効果があります"。それが十分に明確でない場合は、「常に」という言い方をすれば、私はC99の苦情の実装をすべて意味していました。そして、私がこのマクロを探す場所を知らなかったら、私はこのマクロを発明した最初の人間ではないということは無関係です。最後に、ビルドオプションでC99スイッチが有効になっていないと、カーネルコードにどう対応できますか? – lvella

+0

あなたが探している言葉は "ポータブル"です –

答えて

1

はい、有効です。いつも動作します。

ちょうどあなたのforループ、

for(iter_type _iter = (iter_init(container_ptr, &_iter), _iter); \ 
     (elem_ptr = iter_next(&_iterator));) 

、具体的に初期化句iter_type _iter = (iter_init(container_ptr, &_iter), _iter)を取って、あなたはコンマ演算子がここに関与していることがわかります。

カンマ演算子は常に左から右に評価され、各オペランドの間にシーケンスがあります。

+0

実際、コンマ演算子は2項演算子なので、2つのオペランドしか持たない。そして、あなたは_sequence ** point ** _を意味すると思いますか? – Olaf

関連する問題