Dzisiaj podczas pisania kodu Visual C ++ natknąłem się na coś, co mnie zaskoczyło. Wygląda na to, że C ++ obsługuje ++ (inkrementacja) dla bool, ale nie - (dekrementacja). Czy to tylko przypadkowa decyzja, czy jest jakiś powód?
To kompiluje:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
To nie:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
++once
ionce++
pracuj z gcc, ale nie z dekrementami.bool
jest przestarzały, souce .std::exchange(once,false)
(uwaga: nie atomic), jeśli chcesz czegoś, co nie jest przestarzałe.Odpowiedzi:
Pochodzi z historii używania wartości całkowitych jako wartości logicznych.
Jeśli
x
jestint
, ale używam go jako wartości logicznej, zgodnie zif(x)...
tym zwiększanie będzie oznaczało, że niezależnie od jego prawdziwej wartości przed operacją, będzie miała wartość prawdziwościtrue
po niej (z wyjątkiem przepełnienia).Jednak niemożliwe jest przewidzenie wyniku
--
danej wiedzy tylko o wartości prawdziwościx
, ponieważ może to skutkowaćfalse
(jeśli wartość całkowa wynosi 1) lubtrue
(jeśli wartość całkowa jest czymś innym - w szczególności obejmuje to 0 [false
] i 2 lub więcej [true
]).Więc jak krótka ręka
++
zadziałała i--
nie.++
jest dozwolone na bools dla zgodności z tym, ale jego użycie jest przestarzałe w standardzie.Zakłada się, że tylko użyć
x
jako wartość logiczną, co oznacza, że przelew nie może się zdarzyć, aż zrobiłem++
wystarczająco często, aby spowodować przepełnienie na swój własny. Nawet z char jako używanym typem iCHAR_BITS
czymś niskim, jak 5, to 32 razy, zanim to już nie zadziała (to wciąż wystarczający argument, że jest to zła praktyka, nie bronię praktyki, tylko wyjaśniam, dlaczego to działa) w przypadku wersji 32-bitowejint
musielibyśmy oczywiście użyć++
2 ^ 32 razy, zanim pojawi się problem. Z tym,--
że spowoduje to tylkofalse
wtedy, gdy zacznę od wartości 1 fortrue
lub zacznę od 0 i użyłem++
dokładnie raz wcześniej.Inaczej jest, jeśli zaczniemy z wartością, która znajduje się zaledwie kilka poniżej 0. Istotnie, w takim przypadku może chcemy
++
, aby doprowadzić dofalse
wartości takiej, jak w końcu:Jednak ten przykład traktuje
x
jakoint
wszędzie oprócz warunku, więc jest równoważny z:Co różni się od używania tylko
x
jako wartości logicznej.źródło
<limits.h>
nagłówek iCHAR_BIT
makro. Wcześniej, jak przypuszczam, teoretycznie mogły istnieć implementacje, w którychchar
jest węższe niż 8 bitów, ale o ile wiem, nie było żadnych. W szczególności K & R1 (opublikowany w 1978 r.) Wymienia 4 przykładowe implementacje, z których wszystkie mają 8 lub 9 bitówchar
.CHAR_BIT >= 8
. Norma nie uwzględnia celów, w przypadku których jest to trudne. (Oczywiście, możesz mieć niezgodną implementację.)ANSI ISO IEC 14882 2003 (c ++ 03):
5.2.6-2
I nic dziwnego ...
5.3.2-2
Również 5.6.2-1 i 5.3.2-1 wspominają, że ++ dla bools powinno być prawdziwe, a załącznik D-1 mówi, że ++ on bools jest przestarzałe.
źródło
Ze względów historycznych zostało to poparte. Ale pamiętaj, że ... Użycie operandu typu bool z operatorem ++ jest przestarzałe, patrz sekcja 5.3.2 w standardzie C ++ (n3092)
5.3.2 Przyrost i dekrementacja [wyra.pre.incr]
źródło
źródło