GNU/Linux >> Znalost Linux >  >> Linux

V linuxovém jádře 2.6.26 jsem našel #define atomic_read(v) ((v)->counter + 0), proč +0?

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ě + 0jeden 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 #define direktiva 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.


Linux
  1. Linux – Kernel:Podpora jmenných prostorů?

  2. Linux – Proč nemůže jádro spustit inicializaci?

  3. Linux – Jsou různá jádra Linux/unix zaměnitelná?

  1. Proč pr_debug linuxového jádra nedává žádný výstup?

  2. Proč je v Linuxu potřeba upravovat tabulky systémových volání?

  3. Proč je Linux NFS server implementován v jádře na rozdíl od uživatelského prostoru?

  1. Proč je Linux zásadní pro edge computing

  2. Linux – Kernel IP Forwarding?

  3. Proč by někdo chtěl spouštět UserMode Linux (UML)