г>А, ТАК ЧТО ТИХО... ПРИКИНЬ, восп. ЗАНИМАЕТ ЦЕЛЫЙ РАЙТ, А ЗНАЧИТ 7 ИЗ 8 РИТ / it-юмор :: geek (Прикольные гаджеты. Научный, инженерный и айтишный юмор)
Подробнее
г>А,
ТАК ЧТО ТИХО...
ПРИКИНЬ, восп.
ЗАНИМАЕТ ЦЕЛЫЙ РАЙТ, А ЗНАЧИТ 7 ИЗ 8 РИТ
it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Ну раньше тряслись за каждый бит, теперь за каждый метр. Производительность выросла как и требования. Поэтому оптимизацию никто не отменял, просто глупо тратить время на то что никак не влияет на работу программы
самое весёлое начинается когда внутри bool оказывается не 0, не 1 и даже не 0хFF, а какое нибудь скажем 2 или 111
особенно на выкрученной в максимум оптимизации -O3
и у тебя пара сотен тыщь строк кода которые расчёты и проверки по этим булам делают
порой не срабатывают никогда условия вида if (x or (not x)) - это после того как всё внутри ифа вычислено и сокращено по результатам кроме х.
... удачной отладки!
Так и не понял, чем тебя нестандартные булы обидели. asm условные инструкции используют только флаг нулёвости. Или ты грязными руками в биты була полез?
Ну например, когда указатель на бул стал указывать из за другого бага на какой либо мусор.
Или когда парсишь бинарный протокол и пришол из за физического сбоя мусор и пролез в бул.
Пользуйтесь нормальными языками. И знайте свой язык. if(x || !x) срабатывает при любом x. if(x | ~x) так же срабатывает при любом x. И нет, это принципиально разные условия.
Нет, речь именно про взрыво опасную смесь була, мусора в нём значение которого не тру и не фалз и влияния сильной оптимизации. Тогда бажить может и на си и на плюсах и на джаве и в решотке.
Когда работу с булом оптимизатор строит на битовых машинных операциях подразумевая, напримерю что там только младший бит значимый а остальные биты ВСЕГДА равны нулю.
Другой пример: if ( a xor x ) и х=2 подразумевая что true = 1 компилятор при оптимизации заменяет логический ксор на бинарный и не важно какое значение у переменной a в вырожении у а меняется только младший бит а у х установлен второй бит и поэтому - условие срабатывает всегда
А в Джаве, вроде, все вообще очень интересно и размер boolean не определен в спецификации JVM и может меняться в зависимости от версии виртуальной машины.
Учитывая что копируются значения в dword и ecx, в операциях используются 4х байтные регистры и переменные. Наверно это диктовалось производительностью. А локальных переменных всё равно никто не будет 10000 bool делать.
Eй богу, как-будто на хабру написал, а не на джой.
Придрались просто ко всему.
Можно же просто посмеяться типа "хаха, оказывается и ещё хуже бывает" и остаться с хорошим настроением, а не "доказывать_что_в_интернете_ктото_непрпав"жпг
При написании прог для всяких PIC-ов (чистый С), где каждый байт на счету использую структуры типа:
typedef union
{
struct
{
unsigned f_1MS:1; // Флаг таймаута 1 мс
unsigned f_10MS:1; // Флаг таймаута 10 мс
unsigned f_100MS:1; // Флаг таймаута 100 мс
unsigned f_USART_Timeout:1; // Флаг таймаута USART
unsigned f_AD_Cplt:1; // Флаг завершения цикла измерений АЦП
unsigned f_USART_PacketRcvd:1; // Флаг завершения приема пакета USART
unsigned f_KeyPressed:1; // Флаг нажатия кнопки
unsigned f_KeyReleased:1; // Флаг отпускания кнопки
при хорошей оптимизации bool может вообще не занимать нисколько места в памяти потому что сохранение в памяью можно вообще избежать. значение будет вычислено в регистре, использовано в регистре и в нем же стерто. обмена с памятью может и не быть.
А ещё лучше кодить сразу на asm (65816 достаточно хорош).
особенно на выкрученной в максимум оптимизации -O3
и у тебя пара сотен тыщь строк кода которые расчёты и проверки по этим булам делают
порой не срабатывают никогда условия вида if (x or (not x)) - это после того как всё внутри ифа вычислено и сокращено по результатам кроме х.
... удачной отладки!
А вот в сях есть нюанс. if(x == TRUE) как раз может работать некорректно.
Или когда парсишь бинарный протокол и пришол из за физического сбоя мусор и пролез в бул.
Когда работу с булом оптимизатор строит на битовых машинных операциях подразумевая, напримерю что там только младший бит значимый а остальные биты ВСЕГДА равны нулю.
Другой пример: if ( a xor x ) и х=2 подразумевая что true = 1 компилятор при оптимизации заменяет логический ксор на бинарный и не важно какое значение у переменной a в вырожении у а меняется только младший бит а у х установлен второй бит и поэтому - условие срабатывает всегда
Тут согласен, экстремальные оптимизации любят ломать порой даже хорошо написанный код.
C# это про гоняние json-а между сервисами и прочей бизнес логикой, все-таки, нежели байты считать и перекладывать.
Или интерпретируемых языков?
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
Шутка в меме именно про неиспользуемые 7 бит была.
bool a, b;
a = true;
b = true;
Console.WriteLine(b);
компилируется в:
mov dword ptr [ebp-4], 1
mov dword ptr [ebp-8], 1
mov ecx, [ebp-8]
call System.Console.WriteLine(Boolean)
Учитывая что копируются значения в dword и ecx, в операциях используются 4х байтные регистры и переменные. Наверно это диктовалось производительностью. А локальных переменных всё равно никто не будет 10000 bool делать.
bool? x = null;
Nullable y = null;
boll z = null; // error
Придрались просто ко всему.
Можно же просто посмеяться типа "хаха, оказывается и ещё хуже бывает" и остаться с хорошим настроением, а не "доказывать_что_в_интернете_ктото_непрпав"жпг
typedef union
{
struct
{
unsigned f_1MS:1; // Флаг таймаута 1 мс
unsigned f_10MS:1; // Флаг таймаута 10 мс
unsigned f_100MS:1; // Флаг таймаута 100 мс
unsigned f_USART_Timeout:1; // Флаг таймаута USART
unsigned f_AD_Cplt:1; // Флаг завершения цикла измерений АЦП
unsigned f_USART_PacketRcvd:1; // Флаг завершения приема пакета USART
unsigned f_KeyPressed:1; // Флаг нажатия кнопки
unsigned f_KeyReleased:1; // Флаг отпускания кнопки
} Bit;
unsigned char Byte;
} FLAGS_STRUCT;
extern FLAGS_STRUCT Flags;
обращаться потом к ним:
Flags.Bit.xxx = 0;
или ко всей пачке (при инициализации, например):
Flags.Byte = 0;