GNU/Linux >> Linux Esercitazione >  >> Linux

Nel kernel linux 2.6.26, ho trovato #define atomic_read(v) ((v)->counter + 0), perché +0?

Se + 0 non viene utilizzato, sarebbe un lvalue che potresti assegnare per sbaglio, ad esempio

if (atomic_read(v) = 42) {
    ...
}

"funzionerebbe"... Invece di + 0 potresti semplicemente usare unario + , ovvero

(+(v)->counter)

Comunque + 0 ne ha uno buon vantaggio su + in caso generico:+ richiede che l'argomento sia un tipo aritmetico - ma i puntatori non sono di tipo aritmetico. Ancora + 0 funzionerebbe allo stesso modo per i puntatori (e solo per i puntatori, puoi usare &* per convertire lvalue in un valore di espressione; questo è garantito per funzionare anche con puntatori nulli)


È possibile che il file + 0 è stato aggiunto per consentire al compilatore di emettere una diagnostica nel caso ci fosse una ridefinizione delle macro simili a funzioni atomic_read e atomic64_read .

Secondo lo standard C è possibile ridefinire un identificatore che è una macro simile a una funzione se la seconda definizione è anch'essa una macro simile a una funzione che ha lo stesso numero e ortografia dei parametri e le due liste di sostituzione sono identiche.

Dallo standard C11 (n1570), sezione 6.10.3/2:

... Allo stesso modo, un identificatore attualmente definito come macro simile a una funzione non deve essere ridefinito da un altro #define direttiva di preelaborazione a meno che la seconda definizione non sia una definizione di macro simile a una funzione che abbia lo stesso numero e ortografia dei parametri e i due elenchi di sostituzione siano identici.

La versione del kernel (2.6.26) è piuttosto vecchia ma un divieto simile a tale ridefinizione può essere trovato negli standard precedenti fino allo standard C89.

Attualmente le macro atomic_read e atomic64_read sono definiti nel file atomic.h .

Se l'utente li ridefinisse in qualche file sorgente come di seguito:

#define atomic_read(v)      (v)->counter 

Il compilatore emetterebbe una diagnostica sulla ridefinizione. Questo avviso viene emesso perché è presente un + 0 nella definizione atomic_read di nel atomic.h file.

Se non fosse per il + 0 , il compilatore non avrebbe emesso una diagnostica.

Un esempio minimo per dimostrare questo problema:

//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 

Guarda la demo


Impedisce che il risultato sia un lvalue, quindi non puoi assegnarlo erroneamente o prenderne l'indirizzo.


Linux
  1. Linux – Kernel:supporto per gli spazi dei nomi?

  2. Linux:perché non è presente alcun file system Rootfs sul sistema?

  3. Linux:un kernel contaminato in Linux?

  4. Linux:perché il kernel non può eseguire Init?

  5. Linux – I diversi kernel Linux/unix sono intercambiabili?

Comando Dmesg in Linux

Comando Sysctl in Linux

Linux è un sistema operativo o un kernel?

Kernel Linux vs. Kernel Mac

Perché il server Linux NFS è implementato nel kernel anziché nello spazio utente?

Perché qualcuno dovrebbe voler eseguire UserMode Linux (UML)