63 votes

Quelle est la fonction de "(void) (&_min1 == &_min2)" dans la macro min de kernel.h ?

Sur kernel.h min est défini comme suit :

#define min(x, y) ({                \
    typeof(x) _min1 = (x);          \
    typeof(y) _min2 = (y);          \
    (void) (&_min1 == &_min2);      \
    _min1 < _min2 ? _min1 : _min2; })

Je ne comprends pas ce que la ligne (void) (&_min1 == &_min2); fait. C'est une sorte de vérification de type ou autre ?

0 votes

Curieux. Il me semble que la comparaison des adresses forcerait _min1 et _min2, et donc x et y, à être effectivement calculés et stockés, mais cela ne devrait-il pas se produire de toute façon lorsque _min1 est comparé à _min2 à la ligne suivante ?

0 votes

Pour info, la question Macro avec une ligne inhabituelle dans le noyau linux ? a été fusionné avec celui-ci, donc vous avez quelques nouvelles réponses maintenant.

64voto

pmg Points 52636

La déclaration

(void) (&_min1 == &_min2);

est un "no-op" garanti. Donc la seule raison pour laquelle il est là, c'est pour ses effets secondaires.

Mais la déclaration n'a pas d'effets secondaires !

Cependant : il oblige le compilateur à émettre un diagnostic lorsque les types de x et y ne sont pas compatibles .
Notez que le test avec _min1 == _min2 convertirait implicitement l'une des valeurs en l'autre type.

Donc, c'est ce qu'il fait. Il valide, au moment de la compilation, que les types de x et y sont compatibles .

3 votes

Peut-être qu'il est préférable de dire qu'il n'a pas temps de fonctionnement des effets secondaires, mais plutôt compilation effets secondaires.

0 votes

Cela ne me semble pas correct pour une raison quelconque. Si les types sont incompatibles, alors la macro ne fonctionnera pas de toute façon. Par exemple, si vous passez à la macro un struct foo et un int, vous obtiendrez de toute façon une erreur de compilation, même sans cette ligne.

2 votes

@Robert : essayez, par exemple, m = min(42, 43.0); . Avec et sans la déclaration en question.

20voto

Hasturkun Points 18653

Le code dans include/linux/kernel.h parle d'une comparaison de pointeurs "inutile". Il s'agit en fait d'une vérification de type stricte, qui assure que les types de x et y sont les mêmes.

Une incompatibilité de type entraîne une erreur de compilation ou un avertissement.

0 votes

Mais que va-t-il se passer s'ils ne sont pas identiques ? Il semble que le code s'exécutera de toute façon.

0 votes

N'est-ce pas une perte de temps pour le contrôle d'égalité ?

3 votes

Non, c'est un nop. Il est appelé dans un contexte vide, donc les résultats n'ont pas d'importance, un optimiseur l'éliminerait complètement.

12voto

Shafik Yaghmour Points 42198

Cela permet de vérifier le type, l'égalité entre les pointeurs doit être entre des types compatibles et gcc fournira un avertissement pour les cas où ce n'est pas le cas.

Nous pouvons voir que l'égalité entre les pointeurs exige que les pointeurs soient de type types compatibles de la projet de norme C99 section 6.5.9 Opérateurs d'égalité qui dit :

L'une des situations suivantes s'applique :

et comprend :

les deux opérandes sont des pointeurs vers des versions qualifiées ou non qualifiées de types compatibles ;

et nous pouvons trouver ce qu'un type compatible est de la section 6.2.7 Type compatible et type composite qui dit :

Deux types ont un type compatible si leurs types sont les mêmes.

Cette discussion sur osnews couvre également ce sujet et a été inspiré par le Hacks GCC dans le noyau Linux qui contient le même exemple de code. La réponse dit :

a à voir avec la vérification du type.

Réaliser un programme simple :

int x = 10; 
long y = 20;
long r = min(x, y);

Donne l'avertissement suivant : avertissement : la comparaison de types de pointeurs distincts distincts n'est pas accompagnée d'un cast

0 votes

Fusionné à partir de stackoverflow.com/questions/26717636/

7voto

Emil Sit Points 11326

Voir http://www.osnews.com/comments/20566 qui explique :

Cela a à voir avec la vérification de la typologie.

Réaliser un programme simple :

int x = 10; 
long y = 20; 
long r = min(x, y); 

Donne l'avertissement suivant : avertissement : la comparaison de types de pointeurs distincts n'a pas été effectuée par un cast.

4voto

incogn1to Points 409

Réponse trouvée ici

"Cela a à voir avec la vérification de la typologie. Faire un programme simple :

int x = 10; 
long y = 20; 
long r = min(x, y); 

Donne l'avertissement suivant : avertissement : la comparaison de types de pointeurs distincts n'est pas accompagnée d'un cast".

0 votes

Fusionné à partir de stackoverflow.com/questions/26717636/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X