Jika + 0
tidak digunakan, itu akan menjadi lnilai yang dapat Anda tetapkan secara tidak sengaja, yaitu
if (atomic_read(v) = 42) {
...
}
akan "bekerja"... Alih-alih + 0
Anda bisa menggunakan unary +
, yaitu
(+(v)->counter)
Namun + 0
punya satu keuntungan yang baik dibandingkan +
dalam kasus umum:+
mensyaratkan argumen berupa tipe aritmatika - tetapi pointer bukan tipe aritmatika. Namun + 0
akan bekerja untuk pointer sama (dan untuk pointer saja, Anda dapat menggunakan &*
untuk mengubah lvalue menjadi nilai ekspresi; ini dijamin berfungsi bahkan untuk pointer nol)
Kemungkinan + 0
telah ditambahkan untuk kompiler untuk mengeluarkan diagnostik jika ada definisi ulang makro seperti fungsi atomic_read
dan atomic64_read
.
Sesuai dengan standar C, dimungkinkan untuk mendefinisikan ulang pengidentifikasi yang merupakan makro mirip fungsi jika definisi kedua juga merupakan makro mirip fungsi yang memiliki nomor dan ejaan parameter yang sama, dan dua daftar penggantinya identik.
Dari standar C11 (n1570), bagian 6.10.3/2:
... Demikian pula, pengidentifikasi yang saat ini didefinisikan sebagai makro mirip fungsi tidak boleh didefinisikan ulang oleh
#define
lain arahan preprocessing kecuali definisi kedua adalah definisi makro mirip fungsi yang memiliki nomor dan ejaan parameter yang sama, dan kedua daftar penggantinya identik.
Versi kernel (2.6.26) sudah cukup lama tetapi larangan yang serupa pada redefinisi tersebut dapat ditemukan di standar yang lebih lama hingga standar C89.
Saat ini makro atomic_read
dan atomic64_read
didefinisikan dalam file atomic.h
.
Jika pengguna akan mendefinisikan ulang mereka di beberapa file sumber seperti di bawah ini:
#define atomic_read(v) (v)->counter
Kompiler akan mengeluarkan diagnostik tentang redefinisi. Peringatan ini dikeluarkan karena ada + 0
dalam definisi atomic_read
di atomic.h
mengajukan.
Jika bukan karena + 0
, kompiler tidak akan mengeluarkan diagnostik.
Contoh minimal untuk menunjukkan masalah ini:
//atomic.h
#define atomic_read(v) ((v)->counter + 0)
#define atomic64_read(v) ((v)->counter)
//some source file that includes atomic.h
#define atomic_read(v) ((v)->counter) //redefinition error
#define atomic64_read(v) ((v)->counter) //no redefinition error
Lihat Demo
Ini mencegah hasil menjadi lvalue, jadi Anda tidak dapat salah menetapkan atau mengambil alamatnya.