cpp-operators - Cプリプロセッサで利用可能な演算子を把握する
結果
演算子 | 結合規則 | 備考 | |
---|---|---|---|
defined X | (不明) | (Xの前後に一重のみカッコ付加可能、優先順位は不明) | |
() | 左から右 | ||
! ~ + - | 右から左 | (単項演算子) | |
* / % | 左から右 | ||
+ - | 左から右 | ||
<< >> | 左から右 | ||
< <= > >= | 左から右 | ||
== != | 左から右 | ||
& | 左から右 | ||
^ | 左から右 | ||
| | 左から右 | ||
&& | 左から右 | ||
|| | 左から右 | ||
?: | 右から左 | ||
, | 左から右 |
C言語内で使える演算子
→d:id:taiyo:20080203#p1 を参照。
これに加えて、プリプロセッサで独自に使える演算子としては、これ以外に defined がある。
では、プリプロセッサで使えない演算子は?
明らかに使えないだろうという演算子
プリプロセッサには変数がないので、ポインタも配列も構造体もない(ただし関数マクロはある)。
これから、以下の演算子はあきらかに使えないであろう。
演算子 | 結合規則 | 備考 | 使えない理由 |
---|---|---|---|
[] -> . | 左から右 | 配列・ポインタ・構造体へのアクセス | |
++ -- * & (type) | 右から左 | (単項演算子) | 変数・ポインタの操作 |
= += -= *= /= %= &= ^= |= <<= >>= | 右から左 | 変数への代入 |
残りは実際に試してみる
演算子 | 結合規則 | 備考 | |
---|---|---|---|
defined X | (不明) | (優先順位は不明) | |
() | 左から右 | ||
! ~ + - sizeof | 右から左 | (単項演算子) | |
* / % | 左から右 | ||
+ - | 左から右 | ||
<< >> | 左から右 | ||
< <= > >= | 左から右 | ||
== != | 左から右 | ||
& | 左から右 | ||
^ | 左から右 | ||
| | 左から右 | ||
&& | 左から右 | ||
|| | 左から右 | ||
?: | 右から左 | ||
, | 左から右 |
動作確認用に、以下を実行した。
#!/bin/sh TMPSRC=check.c TMPLOG=compile.log trap 'rm -f $TMPSRC $TMPLOG' 0 while read line; do echo -n "CHECK: '$line' ..." cat > $TMPSRC <<EOF #if $line int a = 0; #endif EOF if gcc -E $TMPSRC 2>$TMPLOG >/dev/null; then echo "OK" else echo -n "failed:" sed -n '1s/^[^:]*:[^:]*:[^:]*://p' $TMPLOG fi done <<EOF defined X defined(X) defined ( X ) defined()X defined(defined(X)) defined(defined) defined((X)) defined(((X))) sizeof(int) sizeof int +1 -1 ~1 !1 1 * 1 1 / 1 1 % 1 1 + 1 1 - 1 1 << 1 1 >> 1 1 < 1 1 <= 1 1 > 1 1 >= 1 1 == 1 1 != 1 1 & 1 1 ^ 1 1 | 1 1 && 1 1 || 1 1 ? 1 : 0 1, 1 EOF
これを、gcc-3.4.6で実行した結果は以下:
CHECK: 'defined X' ...OK CHECK: 'defined(X)' ...OK CHECK: 'defined ( X )' ...OK CHECK: 'defined()X' ...failed: operator "defined" requires an identifier CHECK: 'defined(defined(X))' ...failed: missing ')' after "defined" CHECK: 'defined(defined)' ...OK CHECK: 'defined((X))' ...failed: operator "defined" requires an identifier CHECK: 'defined(((X)))' ...failed: operator "defined" requires an identifier CHECK: 'sizeof(int)' ...failed: missing binary operator before token "(" CHECK: 'sizeof int' ...failed: missing binary operator before token "int" CHECK: '+1' ...OK CHECK: '-1' ...OK CHECK: '~1' ...OK CHECK: '!1' ...OK CHECK: '1 * 1' ...OK CHECK: '1 / 1' ...OK CHECK: '1 % 1' ...OK CHECK: '1 + 1' ...OK CHECK: '1 - 1' ...OK CHECK: '1 << 1' ...OK CHECK: '1 >> 1' ...OK CHECK: '1 < 1' ...OK CHECK: '1 <= 1' ...OK CHECK: '1 > 1' ...OK CHECK: '1 >= 1' ...OK CHECK: '1 == 1' ...OK CHECK: '1 != 1' ...OK CHECK: '1 & 1' ...OK CHECK: '1 ^ 1' ...OK CHECK: '1 | 1' ...OK CHECK: '1 && 1' ...OK CHECK: '1 || 1' ...OK CHECK: '1 ? 1 : 0' ...OK CHECK: '1, 1' ...OK
※gcc-4.2.3でも同じ結果。
つまり、definedはカッコ無しかカッコ1つのみが使用可能。sizeofは(かっこ付きでもかっこ無しでも)使えない。それ以外はすべて使用可能。
追記:preprocessor内でsizeofが使えないという話は、C FAQ(Question 10.13)にも書いてあった。