Apa itu operasi&&& di C

195
#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;
}

Output dari program di atas dikompilasi menggunakan gccadalah

0
1
1

Dengan opsi -Wallatau -Waddress, gccmengeluarkan peringatan:

warning: the address of i will always evaluate as true [-Waddress]

Bagaimana cdievaluasi dalam program di atas?

manav mn
sumber
42
Saya percaya itu i && (&i)? Menarik bahwa saya tidak dapat menemukan pos rangkap di SO.
irrelephant
42
while (i &&& i <-- j) {}.
kennytm
8
Bukan duplikat, tapi pertanyaan serupa dan itu tautan bagus
Nathan Cooper

Jawaban:

272

Itu c = i && (&i);, dengan bagian kedua menjadi mubazir, karena &itidak akan pernah dievaluasi false.

Untuk tipe yang ditentukan pengguna, di mana Anda sebenarnya bisa kelebihan beban unary operator &, mungkin berbeda, tapi itu masih ide yang sangat buruk .

Jika Anda menghidupkan peringatan , Anda akan mendapatkan sesuatu seperti:

peringatan: alamat 'i' akan selalu dinilai sebagai 'benar'

Luchian Grigore
sumber
1
Mengapa tidak: c = i & (&&i);; Di mana iada label?
anishsane
4
@anishsane ididefinisikan sebagai intdan tidak ada label dalam pertanyaan. Juga, maksimum mengunyah ...
Luchian Grigore
5
@anishsane: Dan &&operator untuk mengambil alamat label adalah ekstensi gcc yang tidak standar. Tetapi bahkan jika itu standar, aturan mengunyah maksimal akan mencegahnya diurai seperti itu (kecuali Anda memasukkan spasi).
Keith Thompson
Sebenarnya, &ibisa dievaluasi false. Terkadang digunakan untuk default. Contoh: void fn(type& x = *reinterpret_cast<type*>(NULL)); Berapakah nilai &xin fnjika fndipanggil tanpa parameter? Ini 0 alias salah. Namun, dengan menggunakan cara yang dijelaskan, itu akan selalu benar kecuali i == 0, dan jika seseorang menggunakannya seperti yang saya jelaskan, itu akan menjadi benar c = &i && i.
Adrian
@LuchianGrigore: bagaimana bisa begitu?
Adrian
118

Tidak ada &&&operator atau token dalam C. Tetapi operator &&(logis "dan") dan &(unary address-of atau bitwise "dan") memang ada.

Dengan aturan mengunyah maksimal , ini:

c = i &&& i;

setara dengan ini:

c = i && & i;

Set cke 1 jika keduanya idan &ibenar, dan ke 0 jika salah satu dari keduanya salah.

Untuk int, nilai bukan nol adalah benar. Untuk sebuah pointer, nilai non-null apa pun adalah benar (dan alamat suatu objek selalu non-nol). Begitu:

Ini diatur cke 1 jika itidak nol, atau 0jika isama dengan nol.

Yang menyiratkan bahwa &&&sedang digunakan di sini hanya untuk kebingungan yang disengaja. Tugas mungkin termasuk salah satu dari yang berikut:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++
Keith Thompson
sumber