Ага, а еще размер структуры может быть больше чем суммарный размер всех его членов.
тебе лишь бы о членах поговорить
Ну, это лечится #pragma pack
Производительность проседает, лучше попытаться самому упаковать, написав в правильном порядке
В нормальных языках оставляешь прагму компилятору чтобы он их переставил как ему удобно
Так-то паддинги надо учитывать.
А ещё лучше кодить сразу на asm (65816 достаточно хорош).
А ещё лучше кодить сразу на asm (65816 достаточно хорош).
Но ведь структуры можно (нужно) правильно упаковывать
Мне кажется, что правильное согласование звучит как «... всех ЕЁ членов».
Тут что-то по программистке.
Да, и ещё по-руске
ну можно паковать по 8 булов в 1-байтный инт битмаской, и все будет хорошо
struct bit field тебе в помощь.
До тех пор, пока тимлид не отобьёт тебе почки.
Тимлид? Думаешь такое поддерживать нормально? Тут и без тимлида найдут. Имена, явки, чейнджи записаны в гите.
В гите такого не найдешь. А вот в SVN или "корпоративная система хранения на основе winrar на шаре Z://ООО Рогоа и Копыта/софт" чего только не бывает
А ты умеешь сделать больно словами.
а если компания чуть постарше, то arj
Да там еще со времен 64кбит пиздец протокольный
Мы этим страдали во времена спектрума. Каждый бит должен быть использован!
А щас расслабились, понимаешь...
Гиг туда, гиг сюда...
Ну раньше тряслись за каждый бит, теперь за каждый метр. Производительность выросла как и требования. Поэтому оптимизацию никто не отменял, просто глупо тратить время на то что никак не влияет на работу программы
самое весёлое начинается когда внутри bool оказывается не 0, не 1 и даже не 0хFF, а какое нибудь скажем 2 или 111
особенно на выкрученной в максимум оптимизации -O3
и у тебя пара сотен тыщь строк кода которые расчёты и проверки по этим булам делают
порой не срабатывают никогда условия вида if (x or (not x)) - это после того как всё внутри ифа вычислено и сокращено по результатам кроме х.
... удачной отладки!
особенно на выкрученной в максимум оптимизации -O3
и у тебя пара сотен тыщь строк кода которые расчёты и проверки по этим булам делают
порой не срабатывают никогда условия вида if (x or (not x)) - это после того как всё внутри ифа вычислено и сокращено по результатам кроме х.
... удачной отладки!
Теперь у меня есть оправдание тому, что я всегда пишу if (x == true)
В плюсах это равнозначно if(x).
А вот в сях есть нюанс. if(x == TRUE) как раз может работать некорректно.
А вот в сях есть нюанс. if(x == TRUE) как раз может работать некорректно.
вводите давайте уже в своих сях и плюсах ===
Зачем? У нас есть X >>=~*Y;
Так и не понял, чем тебя нестандартные булы обидели. asm условные инструкции используют только флаг нулёвости. Или ты грязными руками в биты була полез?
Ну например, когда указатель на бул стал указывать из за другого бага на какой либо мусор.
Или когда парсишь бинарный протокол и пришол из за физического сбоя мусор и пролез в бул.
Или когда парсишь бинарный протокол и пришол из за физического сбоя мусор и пролез в бул.
Бро, как же это больно.
Указатель на бул как изменится из-за контента була? Вуяд
Пользуйтесь нормальными языками. И знайте свой язык. if(x || !x) срабатывает при любом x. if(x | ~x) так же срабатывает при любом x. И нет, это принципиально разные условия.
Нет, речь именно про взрыво опасную смесь була, мусора в нём значение которого не тру и не фалз и влияния сильной оптимизации. Тогда бажить может и на си и на плюсах и на джаве и в решотке.
Когда работу с булом оптимизатор строит на битовых машинных операциях подразумевая, напримерю что там только младший бит значимый а остальные биты ВСЕГДА равны нулю.
Другой пример: if ( a xor x ) и х=2 подразумевая что true = 1 компилятор при оптимизации заменяет логический ксор на бинарный и не важно какое значение у переменной a в вырожении у а меняется только младший бит а у х установлен второй бит и поэтому - условие срабатывает всегда
Когда работу с булом оптимизатор строит на битовых машинных операциях подразумевая, напримерю что там только младший бит значимый а остальные биты ВСЕГДА равны нулю.
Другой пример: if ( a xor x ) и х=2 подразумевая что true = 1 компилятор при оптимизации заменяет логический ксор на бинарный и не важно какое значение у переменной a в вырожении у а меняется только младший бит а у х установлен второй бит и поэтому - условие срабатывает всегда
Извини, в глаза долблюсь. -О3 не заметил.
Тут согласен, экстремальные оптимизации любят ломать порой даже хорошо написанный код.
Тут согласен, экстремальные оптимизации любят ломать порой даже хорошо написанный код.
Не бывает там не-тру и не-фалз. Любое ненулевое значение это тру.
А в C# так вообще 4 байта (32 бита). Ещё и принимать значение null может, типа ни то, ни другое.
Если так нравится байтики перекладывать, то это явно не к C#, а к Rust/C++/etc.
C# это про гоняние json-а между сервисами и прочей бизнес логикой, все-таки, нежели байты считать и перекладывать.
C# это про гоняние json-а между сервисами и прочей бизнес логикой, все-таки, нежели байты считать и перекладывать.
Ну то есть минус за то, что расширил информацию из поста? Окей :-)
BitArray есть из коробки
Как насчёт джавы с 24 байтами (16 объект и 8 ссылка)?
Или интерпретируемых языков?
Или интерпретируемых языков?
Ну пхп так вообще все варианты сразу хранит, включая строковую интерпретацию :-)
А в Джаве, вроде, все вообще очень интересно и размер boolean не определен в спецификации JVM и может меняться в зависимости от версии виртуальной машины.
ну конкретно сейчас он упомянул, если я правильно помню, не boolean а Boolean.
На пересдачу
И Nullable != bool, так что вторая часть нерелеванта
Четырёхбайтные булы в винапи бывают (typedef int BOOL). В нативном сишарпе бул - 1 байт + выравнивание.
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
И да, я знаю, что одна переменная bool будет размера 4 байта, но сам тип размера 1 байт
Не понял
Локальная переменная будет 4 байта, но если сделать поле в структуре или массиве, то оно будет 1 байт
Хотя нужно смотреть как компилятор их упакует
Если [StructLayout(LayoutKind.Sequential, Pack=1)] не задать, и намудрить с объявлением, то можно 8 байт на один bool потратить
Ничего себе, похоже ты прав. На https://sharplab.io следующий код:
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 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 делать.
Oh, no! Anyway...jpg
bool - структура, и null она не принимает/
bool? x = null;
Nullable y = null;
boll z = null; // error
bool? x = null;
Nullable y = null;
boll z = null; // error
Да он и в C может занять 4 байта (и даже 8) - выравнивание данных какбэ никто не отменял.
больше. ещё же нужно где-то хранить, что это булева переменная, а не какая-то другая.
С чего вдруг нул может принимать?
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; // Флаг отпускания кнопки
} Bit;
unsigned char Byte;
} FLAGS_STRUCT;
extern FLAGS_STRUCT Flags;
обращаться потом к ним:
Flags.Bit.xxx = 0;
или ко всей пачке (при инициализации, например):
Flags.Byte = 0;
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;
Ну, если взять std::vector или std::bitset, то можно и по 1 биту на bool получить
при хорошей оптимизации bool может вообще не занимать нисколько места в памяти потому что сохранение в памяью можно вообще избежать. значение будет вычислено в регистре, использовано в регистре и в нем же стерто. обмена с памятью может и не быть.
Чтобы написать коммент, необходимо залогиниться