Сегодня, когда я писал код Visual C ++, я натолкнулся на кое-что, что меня удивило. Кажется, C ++ поддерживает ++ (приращение) для bool, но не - (декремент). Это случайное решение или есть причина?
Это компилирует:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Это не так:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
++once
иonce++
работайте с gcc, но не с декрементами.bool
устарел, souce .std::exchange(once,false)
(примечание: не атомарно), если вы хотите что-то нерекомендуемое.Ответы:
Это происходит из истории использования целочисленных значений в качестве логических.
Если
x
естьint
, но я использую его как логическое значение согласноif(x)...
then, приращение будет означать, что независимо от его истинного значения перед операцией, оно будет иметь истинное значениеtrue
после него (исключение переполнения).Однако невозможно предсказать результат
--
данного знания только истинного значенияx
, так как это может привести кfalse
(если целое значение равно 1) илиtrue
(если целое значение другое - в частности, это включает 0 [false
] и 2 или подробнее [true
]).Так как короткометражка
++
работала, так и--
не работала .++
разрешено в bools для совместимости с этим, но его использование не рекомендуется в стандарте.Это предполагает, что я использую только
x
как логическое значение, что означает, что переполнение не может произойти, пока я не сделаю++
достаточно часто, чтобы вызвать переполнение самостоятельно. Даже с char в качестве используемого типа иCHAR_BITS
чем-то низким, например, 5, это 32 раза, прежде чем это больше не сработает (это все еще достаточный аргумент в пользу того, что это плохая практика, я не защищаю эту практику, а просто объясняю, почему она работает) для 32-разряднойint
версии нам, конечно, придется использовать++
2 ^ 32 раза, прежде чем это станет проблемой. С участием--
, хотя это будет только в результате ,false
если бы я начал со значением 1 дляtrue
, или начал с 0 и используется++
точно однажды.Это другое дело, если мы начнем со значения, которое всего на несколько единиц ниже 0. Действительно, в таком случае мы могли бы захотеть
++
бы вfalse
конечном итоге получить значение, например:Однако этот пример рассматривается
x
какint
везде, кроме условного, поэтому он эквивалентен:Это отличается от использования только
x
как логического.источник
<limits.h>
заголовок иCHAR_BIT
макрос. До этого, я полагаю, теоретически могли быть реализации, которыеchar
уже 8 бит, но, насколько я знаю, их не было. В частности, K & R1 (опубликовано в 1978 году) перечисляет 4 примера реализации, каждая из которых имеет 8-битную или 9-битную версиюchar
.CHAR_BIT >= 8
. Стандарт не делает поправок на цели, где это сложно. (Конечно, у вас может быть несоответствующая реализация.)ANSI ISO IEC 14882 2003 (c ++ 03):
5.2.6-2
И неудивительно ...
5.3.2-2
Также в 5.6.2-1 и 5.3.2-1 упоминается, что ++ для bools должно быть истинным, а в Приложении D-1 говорится, что ++ для bools устарело.
источник
По историческим причинам это было поддержано. Но обратите внимание, что ... Использование операнда типа bool с оператором ++ устарело, см. Раздел 5.3.2 в стандарте C ++ (n3092)
5.3.2 Увеличение и уменьшение [expr.pre.incr]
источник
источник