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ément). Est-ce juste une décision aléatoire, ou il y a une raison à cela?
Cela compile:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Cela ne:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
++once
etonce++
travaillez avec gcc, mais pas les décrémentations.bool
est obsolète, souce .std::exchange(once,false)
(note: pas atomique), si vous voulez quelque chose de non obsolète.Réponses:
Cela vient de l'histoire de l'utilisation de valeurs entières comme booléens.
Si
x
est unint
, mais je l'utilise comme un booléen,if(x)...
alors l'incrémentation signifiera que quelle que soit sa valeur de vérité avant l'opération, elle aura une valeur de vérité d'true
après elle (sauf dépassement de capacité).Cependant, il est impossible de prédire le résultat d'
--
une connaissance donnée uniquement de la valeur de vérité dex
, car cela pourrait entraînerfalse
(si la valeur intégrale est 1) outrue
(si la valeur intégrale est autre chose - notamment cela inclut 0 [false
] et 2 ou plus [true
]).Donc, en tant que raccourci
++
, a travaillé, et--
n'a pas fait.++
est autorisé sur les booléens pour des raisons de compatibilité avec cela, mais son utilisation est déconseillée dans la norme.Cela suppose que je ne l' utilise qu'en
x
tant que booléen, ce qui signifie que le débordement ne peut pas se produire tant que je ne l'ai pas fait++
assez souvent pour provoquer un débordement par lui-même. Même avec char comme type utilisé etCHAR_BITS
quelque chose de bas comme 5, c'est 32 fois avant que cela ne fonctionne plus (c'est encore un argument suffisant pour que ce soit une mauvaise pratique, je ne défends pas la pratique, j'explique simplement pourquoi cela fonctionne) pour un 32 bits,int
nous devrions bien sûr utiliser++
2 ^ 32 fois avant que ce soit un problème. Avec--
si elle ne permettra d'false
si j'ai commencé avec une valeur de 1 pourtrue
, ou commencé avec 0 et utilisé++
exactement une fois avant.Ceci est différent si nous commençons avec une valeur qui est juste quelques-uns en dessous de 0. En effet, dans un tel cas, nous pourrions vouloir
++
aboutir à lafalse
valeur éventuellement comme dans:Cependant, cet exemple traite
x
commeint
partout sauf le conditionnel, il est donc équivalent à:Ce qui est différent de n'utiliser
x
que comme booléen.la source
<limits.h>
tête et laCHAR_BIT
macro. Avant cela, je suppose qu'il aurait pu théoriquement y avoir des implémentations oùchar
est plus étroit que 8 bits, mais pour autant que je sache, il n'y en avait pas. En particulier, K & R1 (publié en 1978) répertorie 4 exemples d'implémentation, qui ont tous 8 bits ou 9 bitschar
.CHAR_BIT >= 8
. La norme ne tient pas compte des cibles où c'est difficile. (Vous pourriez avoir une implémentation non conforme, bien sûr.)ANSI ISO CEI 14882 2003 (c ++ 03):
5.2.6-2
Et sans surprise ...
5.3.2-2
De plus, les 5.6.2-1 et 5.3.2-1 mentionnent que ++ pour les booléens sera vrai et l'annexe D-1 dit que ++ sur les booléens est obsolète.
la source
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]
la source
la source