Pourquoi le type booléen en C ++ prend-il en charge ++ mais pas -?


29

Pourquoi l'opérateur n'existe-t-il --pas pour bool alors qu'il existe pour opérateur ++?

J'ai essayé en C ++, et je ne sais pas si ma question s'applique à une autre langue. Je serai content de le savoir aussi.

Je sais , je peux utiliser l'opérateur ++avec un bool. Cela rend tout bool égal à vrai.

bool b = false;
b++;
// Now b == true.

Pourquoi ne pouvons-nous pas utiliser l'opérateur --de manière opposée?

bool b = true;
b--;
// Now b == false;

Ce n'est pas très utile, mais je suis curieux.


8
Cette question sur StackOverflow peut être éclairante.
Blrfl

Donc, raison d'histoire. Merci pour le lien. Pouvez-vous écrire une réponse et je la mets comme résolue?
aloisdg dit Réintégrer Monica

Les liens seuls ne font pas de bonnes réponses, et il n'y a pas de bon mécanisme pour marquer cette question sur un doublon de quelque chose sur un autre site SE.
Blrfl

1
Nous devrions donc ouvrir un sujet dans meta.stackexchange.com ou quelque chose. Je pense que vous devriez obtenir du karma pour le bon lien et si quelqu'un vous vote positivement, l'auteur de la réponse originale devrait obtenir du karma. En fait, la question d'origine devrait également obtenir du karma.
aloisdg dit Réintégrer Monica

2
Les doublons entre sites @aloisdg sont un ancien problème sur MSO. Poursuivez les questions liées pour en avoir une vue plus complète.

Réponses:


53

Dans l'ancien temps de C, il n'y avait pas de type booléen. Les gens ont utilisé le intpour stocker des données booléennes, et cela a fonctionné principalement. Zéro était faux et tout le reste était vrai.

Cela signifiait que si vous en preniez un int flag = 0;et plus tard, flag++la valeur serait vraie. Cela fonctionnerait quelle que soit la valeur de l'indicateur (à moins que vous ne le fassiez beaucoup, il roulait et que vous reveniez à zéro, mais ignorons cela) - incrémenter l'indicateur lorsque sa valeur était 1 donnerait 2, ce qui était toujours vrai.

Certaines personnes l'ont utilisé pour définir inconditionnellement une valeur booléenne sur true. Je ne suis pas sûr que cela soit devenu idiomatique , mais c'est dans un certain code.

Cela n'a jamais fonctionné --, car si la valeur était autre que 1 (ce qu'elle pourrait être), la valeur ne serait toujours pas fausse. Et si c'était déjà false ( 0) et que vous avez fait un opérateur de décrémentation dessus, cela ne resterait pas faux.

Lors du déplacement de code de C vers C ++ dans les premiers jours, il était très important que le code C inclus dans C ++ puisse toujours fonctionner. Et donc dans la spécification pour C ++ (section 5.2.6 (c'est à la page 71)), il lit:

La valeur obtenue en appliquant un suffixe ++ est la valeur que l'opérande avait avant d'appliquer l'opérateur. [Remarque: la valeur obtenue est une copie de la valeur d'origine] L'opérande doit être une valeur l modifiable. Le type de l'opérande doit être un type arithmétique ou un pointeur sur un type d'objet complet. Une fois le résultat noté, la valeur de l'objet est modifiée en y ajoutant 1, sauf si l'objet est de type bool, auquel cas il est défini sur true. [Remarque: cette utilisation est déconseillée, voir annexe D.]

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.

Ceci est à nouveau mentionné dans la section 5.3.2 (pour l'opérateur de préfixe - 5.2.6 était sur postfix)

Comme vous pouvez le voir, cela est obsolète (Annexe D dans le document, page 709) et ne doit pas être utilisé.

Mais c'est pourquoi. Et parfois, vous pouvez voir le code. Mais ne le fais pas.


5
"Certaines personnes l'ont utilisé pour définir inconditionnellement une valeur booléenne sur true." Appelons-les fous, pas des gens.
Déduplicateur

@Deduplicator: C'était peut-être une question de performances: le chargement d'une valeur dans une variable peut avoir pris plus de cycles de processeur que l'incrémentation de la variable. Bien sûr, cela n'a probablement pas d'importance sur les ordinateurs modernes.
Giorgio

1
@Giorgio c'est très probable. N'oubliez pas que C a été écrit pour correspondre étroitement au jeu d'instructions PDP-7 et que le PDP-11 avait d'autres réglages. À partir de cela - "Les gens pensent souvent qu'ils ont été créés pour utiliser les modes d'adresse d'incrémentation et de décrémentation automatique fournis par le DEC PDP-11 sur lequel C et Unix sont devenus populaires pour la première fois. Ceci est historiquement impossible, car il n'y avait pas de PDP- 11 lorsque B. a été développé. Le PDP-7, cependant, avait quelques cellules de mémoire "auto-incrémentées", avec la propriété qu'une référence de mémoire indirecte à travers elles incrémentait la cellule. "

@Deduplicator: Dans le code qui utilise des entiers pour les booléens, une variable qui est incrémentée pour chacun ... peu importe ... peut agir à la fois comme compteur (combien de fois elle a été incrémentée) et comme booléenne (a-t-elle été incrémentée du tout ou ne pas).
Keith Thompson


1

Pour comprendre la signification historique de cette question, vous devez considérer le cas du Therac-25. Le Therac-25 était un appareil médical qui délivrait des radiations aux patients cancéreux. Il était en proie à de mauvaises pratiques de programmation qui ont contribué à son mauvais bilan de sécurité (avec plusieurs décès qui lui sont attribués).

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(allez au bas de la page 3)

Chaque passage dans la routine de test de configuration incrémente la vérification de la position du collimateur supérieur, une variable partagée appelée Class3. Si Class3 est différent de zéro, il y a une incohérence et le traitement ne doit pas se poursuivre. Une valeur nulle pour la classe 3 indique que les paramètres pertinents sont cohérents avec le traitement et que le faisceau n'est pas inhibé.

...

Pendant la configuration de la machine, le test de configuration sera exécuté plusieurs centaines de fois car il se replanifie en attendant que d'autres événements se produisent. Dans le code, la variable Class3 est incrémentée de un à chaque passage via le test de configuration. Étant donné que la variable Class3 est de 1 octet, elle ne peut contenir qu'une valeur maximale de 255 décimales. Ainsi, à chaque 256e passage dans le code de test de configuration, la variable déborde et a une valeur nulle. Cela signifie qu'à chaque 256e passage au test de configuration, le collimateur supérieur ne sera pas vérifié et aucune défaillance du collimateur supérieur ne sera détectée. La surexposition s'est produite lorsque l'opérateur a appuyé sur le bouton "set" au moment précis où la classe 3 est passée à zéro. Ainsi, Chkcol n'a pas été exécuté et F $ mal n'a pas été réglé pour indiquer que le collimateur supérieur était toujours en position de champ lumineux. Le logiciel a activé le 25 MeV complet sans la cible en place et sans numérisation. Il en est résulté un faisceau d'électrons hautement concentré, qui a été diffusé et dévié par le miroir en acier inoxydable qui se trouvait sur le chemin.

Le Therac-25 a utilisé quelque chose comme l'équivalent d' operator++un bool. Cependant, le langage de programmation qu'ils utilisaient n'était pas C ++, et leur type de données ne l'était pas bool. Contrairement à la garantie en C ++, cependant, un type entier régulier continue de monter. Leur type de données était l'équivalent de uint8_t.

C ++ a décidé de garder le operator++contact pour les gens habitués à programmer comme ça, mais au lieu d'incrémenter la valeur, il le définit simplement truepour empêcher des choses comme ça.

Notez que operator++(bool)c'est obsolète.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

Annexe D de C ++ 14:

D.1 Opérateur d'incrémentation avec l'opérande bool
L'utilisation d'un opérande de type bool avec l'opérateur ++ est déconseillée (voir 5.3.2 et 5.2.6).


Bien que cela expliquerait pourquoi elle est déconseillée, elle n'explique pas pourquoi elle existe en premier lieu.

Il existe parce que certaines personnes ont défini une valeur booléenne en l'incrémentant lorsque la programmation en C. C ++ a été conçue pour faciliter la transition de C, ils l'ont donc prise en charge avec le booltype. J'essayais juste de donner un exemple historique du moment où les gens ont réellement programmé de cette façon.
David Stone
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.