Pokud + 0 se nepoužívá, byla by to hodnota, kterou byste mohli přiřadit náhodou, tj.
if (atomic_read(v) = 42) {
...
}
by "fungovalo"... Místo + 0 stačí použít unární + , tj.
(+(v)->counter)
Nicméně + 0 má jeden dobrá výhoda oproti + v obecném případě:+ vyžaduje, aby argument byl aritmetického typu - ale ukazatele nejsou aritmetického typu. Přesto + 0 by fungovalo pro ukazatele podobně (a pro ukazatele samotné můžete použít &* převést lvalue na hodnotu výrazu; zaručeně to bude fungovat i pro nulové ukazatele)
Je možné, že + 0 bylo přidáno, aby kompilátor vydal diagnostiku v případě, že došlo k předefinování maker podobných funkcím atomic_read a atomic64_read .
Podle standardu C je možné předefinovat identifikátor, který je makrem podobným funkci, pokud je druhá definice také makro podobné funkci, které má stejný počet a pravopis parametrů a oba seznamy náhrad jsou totožné.
Ze standardu C11 (n1570), sekce 6.10.3/2:
... Stejně tak identifikátor aktuálně definovaný jako funkční makro nesmí být předefinován jiným
#definedirektiva předběžného zpracování, pokud druhá definice není definicí makra podobnou funkci, která má stejný počet a pravopis parametrů a dva seznamy náhrad jsou totožné.
Verze jádra (2.6.26) je poměrně stará, ale podobný zákaz takového předefinování lze nalézt ve starších standardech až po standard C89.
Aktuálně jsou makra atomic_read a atomic64_read jsou definovány v souboru atomic.h .
Pokud by je uživatel předefinoval v nějakém zdrojovém souboru, jak je uvedeno níže:
#define atomic_read(v) (v)->counter
Kompilátor vydá diagnostiku o nové definici. Toto varování bylo vydáno, protože existuje + 0 v definici atomic_read z v atomic.h soubor.
Kdyby nebylo + 0 , kompilátor by nevydal diagnostiku.
Minimální příklad pro demonstraci tohoto problému:
//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
Viz Demo
Zabraňuje tomu, aby výsledek byl lvalue, takže k němu nemůžete chybně přiřadit nebo převzít jeho adresu.