n度あることはn+1度ある

書きたいことを書く 統一性はない

変わったforループの使用法

Linuxカーネルを少しだけ読む必要があり読んでいたのですが、面白いfor文の使われ方を見つけたのでご紹介致します。
該当部分は以下のマクロ

#define for_each_process(p) \
   for (p = &init_task ; (p = next_task(p)) != &init_task ; )

https://elixir.bootlin.com/linux/latest/source/include/linux/sched/signal.h#L542
このマクロは、カーネル内から全てのプロセスに対して、プロセスの情報が格納されているtask_struct構造体を参照するマクロです。
今生成されているプロセスを見ていって、特定の条件に該当するプロセスを探すといった処理で使われていると思います。
forループは基本的にfor(int i=0;i<N;i++) といった書き方をすると思いますが、このマクロには通常カウンタがインクリメント処理されている三項目(?)の部分が省略されています。
一項目の初期化処理を省略する書き方はたまに見ますが、このような書き方を見たのは初めてです。
先に結論を言うと、このような記述にすることによってプロセスを走査する際、PIDが0のプロセス、swapperを走査対象外にすることができます。
forループの処理は
1. 初期化
2. 条件判定
3. ブロック内処理
4. インクリメント
5. 2に戻る
といった処理だと思いますが、この記述だと2の処理内でインクリメント処理を行います。そのため、ループの最初で得るtask_struct構造体は、init_taskであるPID 0のものではなくPID 1のものになるというわけです。
更に、ループの継続条件はinit_taskではないことなので、このマクロ内でswappertask_struct構造体のポインタを得ることはできません。
確かにこの書き方はスマートだと思いますが、あまり書くことはなさそう。

参照:
stackoverflow.com