Aujourd'hui, en écrivant du code Visual C++, je suis tombé sur quelque chose qui m'a surpris. Il semble que C++ supporte ++ (incrémentation) pour bool, mais pas - (décrémentation). C'est juste une décision aléatoire, ou il y a une raison derrière ça?
Cela compile:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Cela ne signifie pas:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
Il vient de l'histoire de l'utilisation de valeurs entières comme booléens.
Si x
est un int
, mais que je l'utilise comme booléen selon if(x)...
alors l'incrémentation signifie que quelle que soit sa valeur de vérité avant l'opération, elle aura un vérité-valeur de true
après (sauf débordement).
Cependant, il est impossible de prédire le résultat de --
ne connaissant que la valeur de vérité de x
, car cela pourrait entraîner false
(si la valeur intégrale est 1) ou true
(si la valeur intégrale est quelque chose sinon - cela inclut notamment 0 [false
] et 2 ou plus [true
]).
Donc, comme un raccourci ++
a fonctionné et --
non.
++
est autorisé sur bools pour la compatibilité avec cela, mais son utilisation est déconseillée dans la norme.
Cela suppose que je niquement utilise x
comme booléen, ce qui signifie qu'un débordement ne peut pas se produire tant que je n'ai pas fait ++
assez souvent pour provoquer un débordement de lui-même. Même avec char comme type utilisé et CHAR_BITS
quelque chose de bas comme 5, c'est 32 fois avant que ça ne marche plus (c'est encore un argument suffisant pour que ce soit une mauvaise pratique, je ne défends pas la pratique, j'explique juste pourquoi ça marche) pour un 32 bits int
nous devons bien sûr utiliser ++
2 ^ 32 fois avant que ce problème ne survienne. Avec --
bien que cela n'aboutisse à false
que si j'ai commencé avec une valeur de 1 pour true
, ou commencé avec 0 et utilisé ++
précisément une fois auparavant.
C'est différent si nous commençons avec une valeur qui est juste en dessous de 0. En effet, dans un tel cas, nous pourrions vouloir ++
pour aboutir à la valeur false
éventuellement comme dans:
int x = -5;
while(++x)
doSomething(x);
Cependant, cet exemple traite x
comme int
partout sauf le conditionnel, il est donc équivalent à:
int x = -5;
while(++x != 0)
doSomething(x);
Ce qui est différent d'utiliser uniquement x
comme booléen.
ANSI ISO IEC 14882 2003 (c ++ 03):
5.2.6-2
L'opérande de postfix - est décrémenté de manière analogue à l'opérateur postfix ++, sauf que l'opérande ne doit pas être de type bool. [Remarque: pour l'augmentation et la diminution du préfixe, voir 5.3.2. ]
Et sans surprise ...
5.3.2-2
L'opérande de préfixe - est modifié en soustrayant 1. L'opérande ne doit pas être de type bool. Les exigences sur l'opérande de prefix - et les propriétés de son résultat sont par ailleurs les mêmes que celles de prefix ++. [Remarque: pour l'incrémentation et la décrémentation du suffixe, voir 5.2.6. ]
De plus, les 5.6.2-1 et 5.3.2-1 mentionnent que ++ pour les bools doit être vrai et l'annexe D-1 dit que ++ sur les bools est déconseillé.
Pour des raisons historiques, cela a été soutenu. Mais notez que ... L'utilisation d'un opérande de type bool avec l'opérateur ++ est déconseillée voir Section 5.3.2 dans la norme C++ (n3092)
5.3.2 Incrémenter et décrémenter [expr.pre.incr]