GNU/Linux >> Tutoriels Linux >  >> Linux

Dans le noyau Linux 2.6.26, j'ai trouvé #define atomic_read(v) ((v)->counter + 0), pourquoi +0 ?

Si + 0 n'est pas utilisé, il s'agirait d'une lvalue que vous pourriez affecter par accident, c'est-à-dire

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

"fonctionnerait"... Au lieu de + 0 vous pouvez simplement utiliser unaire + , c'est-à-dire

(+(v)->counter)

Cependant + 0 en a un bon avantage sur + en cas générique :+ nécessite que l'argument soit un type arithmétique - mais les pointeurs ne sont pas de type arithmétique. Pourtant + 0 fonctionnerait de la même manière pour les pointeurs (et pour les pointeurs seuls, vous pouvez utiliser &* pour convertir lvalue en une valeur d'expression ; ceci est garanti pour fonctionner même pour les pointeurs nuls)


Il est possible que le + 0 a été ajouté pour que le compilateur émette un diagnostic en cas de redéfinition des macros de type fonction atomic_read et atomic64_read .

Selon la norme C, il est possible de redéfinir un identifiant qui est une macro de type fonction si la deuxième définition est également une macro de type fonction qui a le même nombre et la même orthographe de paramètres, et les deux listes de remplacement sont identiques.

De la norme C11 (n1570), section 6.10.3/2 :

... De même, un identifiant actuellement défini comme une macro de type fonction ne doit pas être redéfini par un autre #define directive de prétraitement sauf si la deuxième définition est une définition de macro de type fonction qui a le même nombre et la même orthographe de paramètres, et les deux listes de remplacement sont identiques.

La version du noyau (2.6.26) est assez ancienne, mais une interdiction similaire d'une telle redéfinition peut être trouvée dans les normes plus anciennes jusqu'à la norme C89.

Actuellement les macros atomic_read et atomic64_read sont définis dans le fichier atomic.h .

Si l'utilisateur les redéfinissait dans un fichier source comme ci-dessous :

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

Le compilateur émettrait un diagnostic sur la redéfinition. Cet avertissement est émis car il y a un + 0 dans la définition atomic_read dans le atomic.h dossier.

S'il n'y avait pas le + 0 , le compilateur n'aurait pas émis de diagnostic.

Un exemple minimal pour illustrer ce problème :

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

Voir la démo


Cela empêche le résultat d'être une lvalue, vous ne pouvez donc pas lui attribuer ou prendre son adresse par erreur.


Linux
  1. Linux – Noyau :Prise en charge des espaces de noms ?

  2. Linux - Transfert IP du noyau ?

  3. Linux - Pourquoi n'y a-t-il pas de système de fichiers Rootfs présent sur le système ?

  4. Linux – Un noyau corrompu sous Linux ?

  5. Linux - Pourquoi le noyau ne peut-il pas exécuter Init ?

Pourquoi Linux est essentiel à l'informatique de pointe

Commande Dmesg sous Linux

Commande Sysctl sous Linux

Linux est-il un système d'exploitation ou un noyau ?

Le noyau Linux contre. Mac noyau

Pourquoi Linux ressemble-t-il à Unix si son noyau est monolithique ?