#include <stdio.h>
volatile int i;
int main()
{
int c;
for (i = 0; i < 3; i++)
{
c = i &&& i;
printf("%d\n", c);
}
return 0;
}
gcc
を使用してコンパイルされた上記のプログラムの出力は
0
1
1
とともに -Wall
または-Waddress
オプション、gcc
は警告を発行します。
warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress]
上記のプログラムでc
はどのように評価されていますか?
_&i
_はfalse
に評価されないため、これはc = i && (&i);
です。2番目の部分は冗長です。
実際に単項_operator &
_をオーバーロードできるユーザー定義型の場合、異なる場合がありますが、それでも非常に悪い考えです。
警告を有効にするの場合、次のようになります。
警告:「i」のアドレスは常に「true」と評価されます
Cには&&&
演算子またはトークンはありません。ただし、&&
(論理「and」)および&
(単項アドレスまたはビットごとの「and」)演算子は存在します。
maximal munch ルールにより、これ:
c = i &&& i;
これと同等です:
c = i && & i;
c
と&i
の両方がtrueの場合はi
を1に設定し、どちらかがfalseの場合は0に設定します。
Intの場合、ゼロ以外の値はすべてtrueです。ポインターの場合、null以外の値はすべてtrueです(オブジェクトのアドレスは常にnull以外です)。そう:
c
がゼロ以外の場合はi
を1に設定し、i
がゼロに等しい場合は0
に設定します。
これは、意図的な難読化のためだけに&&&
がここで使用されていることを意味します。割り当ては次のいずれかになります。
c = i && 1;
c = !!i;
c = (bool)i; // C++ or C with <stdbool.h>
c = i ? 1 : 0; /* C */
c = i ? true : false; // C++