web-dev-qa-db-ja.com

Cの&&&操作とは

#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はどのように評価されていますか?

194
manav m-n

_&i_はfalseに評価されないため、これはc = i && (&i);です。2番目の部分は冗長です。

実際に単項_operator &_をオーバーロードできるユーザー定義型の場合、異なる場合がありますが、それでも非常に悪い考えです。

警告を有効にするの場合、次のようになります。

警告:「i」のアドレスは常に「true」と評価されます

270
Luchian Grigore

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++
118
Keith Thompson