bool operator ++ et –

Aujourd’hui, tout en écrivant du code Visual C ++, j’ai rencontré quelque chose qui m’a surpris. Il semble que C ++ supporte ++ (incrément) pour bool, mais pas – (décrémente). C’est juste une décision aléatoire, ou y a-t-il une raison à cela?

Cela comstack:

static HMODULE hMod = NULL; static bool once = false; if (!once++) hMod = LoadLibrary("xxx"); 

Cela ne veut pas:

 static HMODULE hMod = NULL; static bool once = true; if (once--) hMod = LoadLibrary("xxx"); 

    Il provient 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 per 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é true après (en dépassement ).

    Cependant, il est impossible de prédire le résultat de -- sachant seulement la valeur de vérité de x , car cela pourrait avoir pour résultat false (si la valeur intégrale est 1) ou true (si la valeur intégrale est autre chose – notamment cela inclut 0 [ false ] et 2 ou plus [ true ]).

    Donc, une main courte ++ fonctionné, et -- pas.

    ++ est autorisé sur bools pour compatibilité avec cela, mais son utilisation est obsolète dans la norme.


    Cela suppose que j’utilise uniquement x tant que booléen, ce qui signifie que le débordement ne peut pas se produire tant que je n’ai pas fait ++ assez souvent pour provoquer un débordement. Même avec char comme type utilisé et CHAR_BITS quelque chose comme 5, c’est 32 fois avant que cela ne fonctionne plus (c’est toujours un argument suffisant pour que ce soit une mauvaise pratique, je ne défends pas la pratique, juste expliquer pourquoi cela fonctionne) ) pour un int 32 bits, nous devrons bien sûr utiliser ++ 2 ^ 32 fois avant que cela ne soit un problème. Avec -- bien que cela ne se traduise par un false si j’ai démarré avec une valeur de 1 pour true , ou commencé avec 0 et utilisé ++ précisément une fois auparavant.

    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 que ++ aboutisse finalement à la valeur false telle que dans:

     int x = -5; while(++x) doSomething(x); 

    Cependant, cet exemple traite x comme un int partout sauf le conditionnel, donc c’est équivalent à:

     int x = -5; while(++x != 0) doSomething(x); 

    Ce qui est différent de n’utiliser que 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’incrémentation et la décrémentation du préfixe, voir 5.3.2. ]

    Et sans surprise …

    5.3.2-2

    L’opérande du préfixe – est modifié en soustrayant 1. L’opérande ne doit pas être de type bool. Les exigences sur l’opérande du préfixe – et les propriétés de son résultat sont par ailleurs les mêmes que celles du préfixe ++. [Remarque: Pour l’incrémentation et la décrémentation postfixes, voir 5.2.6. ]

    De même, les versions 5.6.2-1 et 5.3.2-1 mentionnent que ++ pour les bools doit être vrai et que l’annexe D-1 indique que ++ sur bools est obsolète.

    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 obsolète, voir Section 5.3.2 du standard C ++ (n3092)

    5.3.2 Incrémenter et décrémenter [expr.pre.incr]

    • L’opérande de préfixe ++ est modifié en ajoutant 1 ou défini sur true s’il s’agit de bool (cette utilisation est obsolète). L’opérande doit être une lvalue modifiable. Le type de l’opérande doit être un type arithmétique ou un pointeur sur un type d’object complètement défini. Le résultat est l’opérande mis à jour. c’est une lvalue, et c’est un champ binary si l’opérande est un champ binary. Si x n’est pas de type bool, l’expression ++ x est équivalente à x + = 1 [Note: voir les discussions des opérateurs d’addition (5.7) et d’affectation (5.17) pour plus d’informations sur les conversions. —End note]
    • L’opérande du préfixe – est modifié en soustrayant 1. L’opérande ne doit pas être de type bool. Les exigences sur l’opérande du préfixe – et les propriétés de son résultat sont par ailleurs les mêmes que celles du préfixe ++.
    • Avec les anciennes normes (C ++ 98) ce n’est pas une erreur.
    • Avec les nouvelles normes, l’incrémentation d’un booléen est obsolète. (C ++ 11)
    • Vous pouvez utiliser l’incrémentation sur un booléen jusqu’à C ++ 17.