bool opérateur ++ et --
Aujourd'hui, alors que l'écriture de code de Visual C++, j'ai trouvé quelque chose qui m'a surpris. Il semble que C++ prend en charge ++ (incrémentation) pour le type bool, mais pas -- (décrémentation). Il c'est juste une décision au hasard, ou il y a une raison derrière tout cela?
Cette compile:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Ce n'est pas:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
- hm, même pour xcode et le compilateur gcc
- Yep,
++once
etonce++
travail avec gcc, mais pas le décrémente. - Peut-être en mesure de baliser "l'histoire" au lieu de "opérateur-mot-clé", c'est donc regroupés avec tous les autres du plaisir explications du pourquoi de diverses choses folles sont raisonnables si vous considérez l'histoire? 🙂
- Note de C++17 de la pré-opérateur d'incrémentation pour
bool
est obsolète, source.
Vous devez vous connecter pour publier un commentaire.
Il s'agit de l'histoire de l'utilisation de valeurs de type entier comme des booléens.
Si
x
est unint
, mais je l'utilise comme une valeur booléenne que parif(x)...
puis incrémentation signifie que, quelle que soit sa valeur de vérité avant l'opération, elle aura la valeur de vérité detrue
après (sauf dépassement de capacité).Cependant, il est impossible de prédire le résultat de
--
donné connaissance de la valeur de vérité dex
, car il pourraitfalse
(si l'intégrale est égale à 1) outrue
(si la valeur intégrale est rien d'autre - notamment ceci inclut 0 [false
] et 2 ou plus [true
]).Ainsi que d'un court de main
++
travaillé, et--
n'a pas.++
est autorisée sur les booléens pour la compatibilité avec cela, mais son utilisation est déconseillée dans la norme.Cela suppose que je seulement utilisation
x
comme un booléen, ce qui signifie que le débordement ne peut pas se produire jusqu'à ce que j'ai fait++
assez souvent à cause d'un débordement sur son propre. Même avec un char comme le type utilisé etCHAR_BITS
quelque chose faibles comme 5, c'est 32 fois avant que cela ne fonctionne plus (c'est encore un argument suffisant pour qu'il soit une mauvaise pratique, je ne suis pas la défense de la pratique, tout en expliquant pourquoi il fonctionne) pour un 32 bitsint
bien entendu, nous aurions dû utiliser++
2^32 fois avant que ce soit un problème. Avec--
bien qu'il ne fait qu'false
si j'ai commencé avec une valeur de 1 pourtrue
, ou a commencé avec 0 et utilisé++
précisément une fois avant.Cela est différent si on commence avec une valeur qui est juste un peu en dessous de 0. En effet, dans un tel cas, nous pourrions vouloir
++
de résultat dans lafalse
valeur, éventuellement, comme dans:Cependant, cet exemple traite
x
comme unint
partout à l'exception du conditionnel, il est donc équivalente à:Qui est différent à l'utilisation d'
x
comme une valeur booléenne.int
valeurs ne sont pas les++ -> always true
test. Si c'étaitunsigned int
sur l'autre main...int
de la valeur, mais on le passe.-1
échoue, et le maximumunsigned int
échoue, mais tous les autres sont le résultat en vrai.--
avec tous positifs...CHAR_BIT
(pasCHAR_BITS
) est nécessaire pour être moins 8.<limits.h>
en-tête et leCHAR_BIT
macro. Avant cela, je suppose qu'il pourrait théoriquement avoir été implémentations oùchar
est plus étroite que 8 bits, mais autant que je sache, il n'y en avait aucune. En particulier, K&R1 (publié en 1978) liste 4 exemple implémentations, qui ont tous la 8-bits ou 9 bitschar
.char
différente de la machine de la taille en octets serait donc seulement 5 bits. C'est délibérément un exemple extrême, si.CHAR_BIT >= 8
. Le standard ne veut pas prendre en compte les cibles où c'est difficile. (Vous pourriez avoir une non-conformité de la mise en œuvre, bien sûr.)ANSI ISO IEC 14882 2003 (c++03):
5.2.6-2
Et sans surprise...
5.3.2-2
Également la 5.6.2-1 et 5.3.2-1 mentionner que ++ pour les booléens doivent être véridiques et à l'Annexe D-1 dit que ++ sur les booléens dans obsolète.
Due à des raisons historiques, cela a été pris en charge. Mais notez que ...
L'utilisation d'un opérande de type bool avec l'opérateur ++ est obsolète, voir la Section 5.3.2 de la Norme C++ (n3092)
5.3.2 d'Incrémentation et de décrémentation [expr.pré.incr]
en ajoutant 1, ou la valeur true si elle est
bool (cette utilisation est déconseillée). L'
l'opérande doit être modifiable lvalue.
Le type de l'opérande doit être une
l'arithmétique de type ou un pointeur vers un
complètement définie par type d'objet. L'
le résultat est la mise à jour de l'opérande; il est
une lvalue, et c'est un peu de champ si
l'opérande est un peu de champ. Si x est
pas de type booléen, l'expression ++x
est équivalent à x+=1 [ Note: voir la
les discussions de l'addition (5.7) et
opérateurs d'affectation (5.17) pour
informations sur les conversions. —la note de fin de
]
en soustrayant 1. L'opérande est
ne pas être de type bool. Les exigences
sur l'opérande de préfixe -- et l'
propriétés de son résultat sont
sinon, les mêmes que ceux de préfixe
++.