35 votes

Pourquoi utiliser !! (condition) au lieu de (condition)?

J'ai vu du code où les gens ont utilisé des clauses conditionnelles avec deux "!"

 #define check_bit(var, pos)       (!!((var) & (1 << (pos))))
#define likely(x)       __builtin_expect(!!(x),1)
#define unlikely(x)     __builtin_expect(!!(x),0)
 

Voici quelques exemples que je pourrais trouver.

Y at-il un avantage à utiliser !!(condition) sur (condition) ?

34voto

Shafik Yaghmour Points 42198

Eh bien, si la variable que vous postulez !! n'est pas déjà un bool(zéro ou un), alors il sera de normaliser la valeur: 0 ou 1.

À l'égard __builtin_expect ce noyau débutants thread traite de la notation et de l'une des réponses qui explique (c'est moi qui souligne):

La signature de l' __builtin_attendent

http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html) est:

long __builtin_attendent (longue exp, longtemps c)

Notez que l'exp paramètre doit être une partie intégrante de l'expression, donc pas de pointeurs ou flottants types là. La double négation gère la conversion de ces types de partie intégrante des expressions automatiquement. De cette façon, vous pouvez simplement écrire: probable(ptr) plutôt probable(ptr != NULL).

Pour référence dans C99 bool macro s'étend à d' _Bool, true s'étend à d' 1 et false s'étend à d' 0. Les détails sont donnés dans le projet de norme section 7.16 type Booléen et les valeurs .

Négation logique est couvert en 6.5.3.3 des opérateurs arithmétiques Unaires au paragraphe 5:

Le résultat de la négation logique de l'opérateur ! est 0 si la valeur de son opérande compare inégales à 0, 1 si la valeur de son opérande compare égal à 0. Le résultat est de type int. L'expression !E est équivalent à (0==E).

6voto

Keith Thompson Points 85120

Unaire ! logique opérateur de négation, appliquée à n'importe quel scalaire, les rendements de l' int valeur 0 si son opérande est non nul, 1 si l'opérande est égal à zéro. Citant le standard:

L'expression !E est équivalent à (0==E).

En appliquant ! deux fois pour la même valeur scalaire donne un résultat qui est vrai si la valeur est true, false si la valeur est false -- mais le résultat est normalisé 0 ou 1.

Dans la plupart des cas, ce n'est pas nécessaire, puisque toute valeur scalaire peut être utilisé directement comme une condition. Mais dans certains cas, vous avez réellement besoin d'un 0 ou 1 de la valeur.

En C99 ou plus tard, le casting de l'expression d' _Bool (ou bool si vous avez #include <stdboo.h> se comporte de la même façon et pourrait être considéré comme plus claire. Mais (a) le résultat est de type _Bool plutôt que d' int, et (b) si vous utilisez un pré-compilateur C99 qui ne prend pas en charge _Bool et que vous avez défini votre propre bool type, il ne' se comportent de la même manière que le C99 est _Bool.

4voto

Elliott Frisch Points 45093

Le plus gros que je peux voir, c'est qu'il va forcer (ou normaliser) la valeur dans 1 ou 0 (c'est une valeur booléenne), quelle que soit la manière dont x ou var expression se développe (par exemple, char ou double ou int ou etc.).

2voto

Lochlan Points 618

Il jette un booléen, ce qui peut parfois être utile.

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