🕌
カーネルで使われる三項演算子
カーネルで使われる三項演算子
三項演算子 は英語でternary operatorsです。
A ? B: C
AがTrueならBを返し、FalseならCを返す。
通常はif文を使うため、三項演算子は使わないのですが。
カーネルでは特殊な使い方をしていますので、見ていきます。
#define to_cpumask(bitmap) \
((struct cpumask *)(1 ? (bitmap) \
: (void *)sizeof(__check_is_bitmap(bitmap))))
static inline int __check_is_bitmap(const unsigned long *bitmap)
{
return 1;
}
初め見たとき、これは一体何がしたいのか首をかしげました。
まずAに1が設定されているため常にTrueです。
そのままbitmapを返しているだけ。
2つのことをチェックしています。
A ? B: Cですが、BとCは同じ型であることが要求されます。
bitmapは(void *)型であること。
もう一つはbitmapは (const unsigned long*)型に変換可能であること。
最後に(cpumask *)型に変換して返しています。
つまりカーネルの三項演算子は型チェックに使われます。
ソースを読むぶんには無視しても構いません。
最初からcpumaskで変数登録しておけば変換不要になると思うのだが、それは不明。
それっぽいプログラムを作成した。
#include <stdio.h>
#define to_cpumask(bitmap) ((struct cpumask *)(1 ? (bitmap): (void *)sizeof(__check_is_bitmap(bitmap))))
static inline int __check_is_bitmap(const unsigned long *bitmap)
{
return 1;
}
unsigned long x[1];
int z;
struct cpumask {
unsigned long bits[1];
};
int main()
{
struct cpumask *y;
x[0] = 100;
x[1] = 200;
y = to_cpumask(x);
//y = to_cpumask(z); 有効にすると警告出る
//z = to_cpumask(x); 有効にすると警告出る
printf("x[0] %lu\n", x[0]);
printf("x[1] %lu\n", x[1]);
printf("y->bits[0] %lu\n", y->bits[0]);
printf("y->bits[1] %lu\n", y->bits[1]);
return 0;
}
Discussion