I found this in linux-2.6.26 (linux-2.6.26/include/asm-alpha/atomic.h), and donot know why +0 here.
#define atomic_read(v) ((v)->counter + 0)
#define atomic64_read(v) ((v)->counter + 0)
If + 0
is not used, it would be an lvalue that you could assign to by accident, i.e.
if (atomic_read(v) = 42) {
...
}
would "work"... Instead of + 0
you could just use unary +
, i.e.
(+(v)->counter)
However + 0
has one good advantage over +
in generic case: +
requires that the argument be an arithmetic type - but pointers are not of arithmetic type. Yet + 0
would work for pointers alike (and for pointers alone, you can use &*
to convert lvalue to a value of expression; this is guaranteed to work for even null pointers)
It is possible that the + 0
was added for the compiler to issue a diagnostic in case there was a redefinition of the function-like macros atomic_read
and atomic64_read
.
As per the C standard it is possible to redefine an identifier which is a function-like macro if the second definition is a also function-like macro that has the same number and spelling of parameters, and the two replacement lists are identical.
From C11 standard (n1570), section 6.10.3/2:
... Likewise, an identifier currently defined as a function-like macro shall not be redefined by another
#define
preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
The kernel version (2.6.26) is quite old but similar prohibition on such redefinition can be found in older standards upto the C89 standard.
Currently the macros atomic_read
and atomic64_read
are defined in the file atomic.h
.
If the user would redefine them in some source file as below:
#define atomic_read(v) (v)->counter
The compiler would issue a diagnostic about the redefinition. This warning is issued because there is a + 0
in the definition atomic_read
of in the atomic.h
file.
If it were not for the + 0
, the compiler would not have issued a diagnostic.
A minimal example to demonstrate this issue:
//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
See Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With