|
ユーザーのアルビレオです。
>if( *psz < '0' | *psz > '9' ) {
>
>という一行がありますが,手元のVC++.NETでコンパイルすると
>
>warning C4554: '|' : 演算子の優先順位に問題があります。カッコを使用して優先
>順位を明確にしてください
>
>と警告が出ます.ここはどのような意図なのでしょうか?
これはこれで正しいソースです。
何らかの意図があるのはコンパイラの方でして…
以下は純粋にC言語とコンパイラの話です。
if( a + b > 0 )
という式が書かれていた場合、普通なら人間は「aとbを足した結果が0より大き
い」という意味に受け取ります。
この「人間の感覚」に合わせるためにCの仕様として「比較演算子は算術演算子
より優先順位が低い」というルールになっています。
ところが「|」や「&」は例外的に比較演算子より低い優先順位になります。
(C言語の歴史的な事情からこうなったのですが、長くなるので理由は省略)
この結果、
if( a | b > 0 )
という式は一見「(a | b) > 0」という意味に見えますが、上に書いたルールに
よってコンパイラは「a | (b > 0)」と解釈します。
これはわりとよくある間違いなので、たいていのコンパイラでは「|」や「&」と
比較演算子がかっこなしで並んでいた場合は警告を出すようになっています。
元のソースは「*psz < ('0' | *psz) > '9'」ではなく「(*psz < '0') | (*psz
> '9')」という意図であることはひと目でわかりますよね?
つまりCの仕様どおりの優先順位の評価で問題ありません。
でもコンパイラは「ひょっとしたら間違っているのかも」と警告を出しているわ
けです。
># |が一本足りないのかなぁ?と勝手に思ってたりするのですが......
おっしゃるとおり「|」を「||」にすれば警告は出なくなりますが、動作はいっ
しょです。警告が出るか出ないかの違いしかありません。
(ひょっとすると、最適化の結果には違いがあるかもしれませんが)
※おまけ
「if( (BYTE)(*psz - '0') <= 9 )」と書くと一回の比較ですむので、ちょっぴ
り高速化できます。
でもよほどのことがない限りは、こんなひどいコードは書かない方がいいです。
|
|