GNU/Linux >> Tutoriales Linux >  >> Linux

En el kernel de Linux 2.6.26, encontré #define atomic_read(v) ((v)->counter + 0), ¿por qué +0?

Si + 0 no se usa, sería un valor l que podría asignar por accidente, es decir,

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

"funcionaría"... En lugar de + 0 podrías usar unario + , es decir,

(+(v)->counter)

Sin embargo + 0 tiene uno buena ventaja sobre + en caso genérico:+ requiere que el argumento sea un tipo aritmético - pero los punteros no son de tipo aritmético. Sin embargo, + 0 funcionaría para punteros por igual (y solo para punteros, puede usar &* para convertir lvalue en un valor de expresión; esto está garantizado para funcionar incluso con punteros nulos)


Es posible que el + 0 se agregó para que el compilador emita un diagnóstico en caso de que haya una redefinición de las macros similares a funciones atomic_read y atomic64_read .

Según el estándar C, es posible redefinir un identificador que es una macro similar a una función si la segunda definición también es una macro similar a una función que tiene el mismo número y ortografía de parámetros, y las dos listas de reemplazo son idénticas.

Del estándar C11 (n1570), sección 6.10.3/2:

... Del mismo modo, un identificador actualmente definido como una macro similar a una función no será redefinido por otro #define directiva de preprocesamiento a menos que la segunda definición sea una definición de macro similar a una función que tenga el mismo número y ortografía de parámetros, y las dos listas de reemplazo sean idénticas.

La versión del kernel (2.6.26) es bastante antigua, pero se puede encontrar una prohibición similar sobre dicha redefinición en estándares más antiguos hasta el estándar C89.

Actualmente las macros atomic_read y atomic64_read se definen en el archivo atomic.h .

Si el usuario los redefiniera en algún archivo fuente como se muestra a continuación:

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

El compilador emitiría un diagnóstico sobre la redefinición. Esta advertencia se emite porque hay un + 0 en la definición atomic_read de en el atomic.h expediente.

Si no fuera por el + 0 , el compilador no habría emitido un diagnóstico.

Un ejemplo mínimo para demostrar este 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 

Ver demostración


Evita que el resultado sea un valor l, por lo que no puede asignarlo incorrectamente ni tomar su dirección.


Linux
  1. Linux – Kernel:¿Soporte de espacios de nombres?

  2. Linux – ¿Reenvío de IP del kernel?

  3. Linux:¿por qué existe una política de kernel de Linux para nunca romper el espacio del usuario?

  4. Linux:¿por qué el kernel no puede ejecutar Init?

  5. ¿Por qué pr_debug del kernel de Linux no da ningún resultado?

Comando Dmesg en Linux

Comando Sysctl en Linux

¿Linux es un sistema operativo o un kernel?

Núcleo de Linux vs. Núcleo de Mac

¿Por qué alguien querría ejecutar UserMode Linux (UML)?

¿Por qué Linux es similar a Unix si su núcleo es monolítico?