Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
Я вот сходу не скажу, в каком порядке идут биты в битовых полях. Я не помню, что об этом говорит стандарт и может ли порядок различаться в разных компиляторах и на разных платформах.
Пиздец там тонкий лёд, конечно... Стандарт возлагает ответственность на конпелятор, конпелятор на ABI, а в x86_64 ABI написана какая-то мутная хуйня, которая ничего не объясняет:
- bit fields are allocated from right to left
- bit-fields must be contained in a storage unit appropriate for its declared type
- bit-fields may share a storage unit with other struct / union members
Что такое "appropriate"? Самый маленький storage unit, который вмещает тип? Или можно и больше?
Что такое "may share"? Т.е. при каких-то условиях могут и в разные юниты попасть?
Блядь, и это формальная спецификация?
struct foo1 { uint8_t a : 3; uint8_t b : 3; uint8_t c : 3; } // 00bbbaaa 00000ccc
struct foo2 { uint8_t a : 3; uint8_t b : 3; uint16_t c : 3; } // ccbbbaaa 0000000c
Т.е. 16-битный storage unit вполне так appropriate для 8-битного поля. Но только если рядом есть другие 16-битные поля, иначе он уже не особо appropriate (по крайней мере для gcc). Где блядь об этом написано?
> вообще не угадаешь, как компилятор разложит биты
Именно так. Он походу пытается добиться какого-то баланса между пирфомансом и размером, из-за этого алгоритм совсем неочевидный.
И получается что вменяемого, документированного ABI у сишки для x86_64 нет. Всё работает только за счёт того, что конпеляторы подстраиваются под своих старших собратьев.
Кстати, тут ещё union используется в качестве reinterpret_cast. Так до сих пор делают, хотя стандарт то ли на сишку, то ли на кресты не рекомендует так делать. По стандарту union используется для экономии памяти, а нее для отображения типа на тип.
Видимо, производители компиляторов поддерживают этот хак, иначе куча программ сломается.
Можно получать доступ к соответствующим полям структур в юнионах, если они имеют compatible types. Только я не могу найти что является цомпатибле тупес.
Вроде как в с99 это уже разрешили.
Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one. The rationale was that the behaviour would then depend on the representations of the values. Since this point is often misunderstood, it might well be worth making it clear in the Standard.
[...]
To address the issue about "type punning", attach a new footnote 78a to the words "named member" in 6.5.2.3#3: 78a If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.
Вспомнил грязный хак в «Паскале»: там множества реализовали битовыми масками. Если тип объявлен как set of 0..7, то [0] представлено единицей, [1] представлено двойкой, [0, 1] представлено тройкой. Дизъюнкцию и конъюнкцию можно вычислять как объединение и пересечение множеств соответственно.
Реализация-то хорошая, сверхбыстрая. Только в ТП мощность множеств ограничили 256 элементами (в этом случае представление занимает 256 бит = 32 байта).
Я про возможный хак для использования таких множеств вместо битовых полей. Типа:
type T = set of 0..7;
var S: T; I: Integer;
begin
Move(I, S, 1);
S := S * [0, 1]; // экв. I := I and 3;
S := S - [1]; // экв. I := I and not 1;
S := S + [2]; // экв. I := I or 4;
Move(S, I, 1);
end;
Во Фрипаскаль добавили симметричную разность (><, экв. xor) и проверку на подмножество и надмножество (<= и >=).
SoC — это то, что раньше у нас называли «однокристальная ЭВМ». А микроконтроллерами обычно называют что-то попроще, типа контроллера флоппика, заточенного под определённую задачу.
каким образом в битах оказываются правильные значения?
я вижу юнион, но внутри же у него int, почему каждый из них занимает ровно один бит, а не 32 или сколько там предусмотрено платформой?
upd:
unsigned int bit1 : 1;
это указание длины что ли?
так можно было?
в пизду, будут джаваскриптером
> каким образом в битах оказываются правильные значения?
Считай это сахарок над побитовыми оперециями, нопремер first_byte.bit2 = 1 скомпилица в first_byte.byte |= 0x02
Выравнивание storage unit'а для битовых полей соответствует тому типу, который попросили. В данном случае unsigned int. Т.е. эта структура, судя по всему, будет состоять из одного юнита на 4 байта из которых только 8 бит юзаются под битовые поля.
>т когда оступишься и нарушишь Стандарт.
Чтобы первые пол года работать правильно, а потом выкинуть половину твоей программы в самый неожиданный момент
Общее правило гласит: если хакер попал к тебе в шел (в смысле зашел под обычным юзером по ссш на юникс или по рдп на винду), то можешь сразу дать ему админские права на машину, потому что получение их лишь вопрос времени
Noodles # 0
Кто-то прогуливал мат логику.
bormand # 0
З.Ы. Тут же просто first_byte.byte |= second_byte.byte?
guest # 0 ⇈
codemeow # 0 ⇈
bormand # 0 ⇈
codemeow # 0 ⇈
Noodles # 0 ⇈
bormand # 0 ⇈
Noodles # 0 ⇈
bormand # 0 ⇈
Noodles # 0 ⇈
Какой багор )))
HoBorogHuu_nemyx # 0 ⇈
3.14159265 # 0
С одной стороны на лабу не похоже.
>return EXIT_FAILURE;
> strerror( errno )
И всё довольно вменяемо.
С другой, нумерация bit1 с единицы и реализация побитовой илишни руками.
guest # 0 ⇈
j123123 # 0 ⇈
bormand # 0 ⇈
А я вот битовые структуры вообще не умею юзать... Мне проще через & и | побитоёбить.
HoBorogHuu_nemyx # 0 ⇈
bormand # 0 ⇈
Но в пределах одного ABI работать будет, конечно.
bormand # 0 ⇈
- bit fields are allocated from right to left
- bit-fields must be contained in a storage unit appropriate for its declared type
- bit-fields may share a storage unit with other struct / union members
bormand # 0 ⇈
Что такое "may share"? Т.е. при каких-то условиях могут и в разные юниты попасть?
Блядь, и это формальная спецификация?
Т.е. 16-битный storage unit вполне так appropriate для 8-битного поля. Но только если рядом есть другие 16-битные поля, иначе он уже не особо appropriate (по крайней мере для gcc). Где блядь об этом написано?
bormand # 0 ⇈
bormand # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
Значит, неупакованный вариант можно использовать только для временного хранения.
bormand # 0 ⇈
Именно так. Он походу пытается добиться какого-то баланса между пирфомансом и размером, из-за этого алгоритм совсем неочевидный.
И получается что вменяемого, документированного ABI у сишки для x86_64 нет. Всё работает только за счёт того, что конпеляторы подстраиваются под своих старших собратьев.
guest # 0 ⇈
Помоему это заивисит от проца
Fike # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
Fike # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
Видимо, производители компиляторов поддерживают этот хак, иначе куча программ сломается.
Noodles # 0 ⇈
codemeow # 0 ⇈
Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one. The rationale was that the behaviour would then depend on the representations of the values. Since this point is often misunderstood, it might well be worth making it clear in the Standard.
[...]
To address the issue about "type punning", attach a new footnote 78a to the words "named member" in 6.5.2.3#3: 78a If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.
DaveMustAim # 0 ⇈
bormand # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
bormand # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
Я про возможный хак для использования таких множеств вместо битовых полей. Типа:
Во Фрипаскаль добавили симметричную разность (><, экв. xor) и проверку на подмножество и надмножество (<= и >=).
ObeseYoung # 0 ⇈
Есть же в паскакале obsolete для такого. Или на крайний случай можно кастануть.
HoBorogHuu_nemyx # 0 ⇈
bormand # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
3.14159265 # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
bormand # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
Так?
ObeseYoung # 0 ⇈
bormand # 0 ⇈
Хотя при желании можно запихать, конечно. Только это будет просто inflate без gzopen/gzread и прочего нинужного обвеса.
codemeow # 0 ⇈
Fike # 0
каким образом в битах оказываются правильные значения?
я вижу юнион, но внутри же у него int, почему каждый из них занимает ровно один бит, а не 32 или сколько там предусмотрено платформой?
upd:
это указание длины что ли?
так можно было?
в пизду, будут джаваскриптером
ObeseYoung # 0 ⇈
32 бита инт небось для выравнивания выбран.
HoBorogHuu_nemyx # 0 ⇈
https://en.cppreference.com/w/c/language/bit_field
Fike # 0 ⇈
HoBorogHuu_nemyx # 0 ⇈
ObeseYoung # 0 ⇈
Rooster # 0 ⇈
ObeseYoung # 0 ⇈
guest # 0 ⇈
Rooster # 0 ⇈
Считай это сахарок над побитовыми оперециями, нопремер first_byte.bit2 = 1 скомпилица в first_byte.byte |= 0x02
Fike # 0 ⇈
bormand # 0 ⇈
Выравнивание storage unit'а для битовых полей соответствует тому типу, который попросили. В данном случае unsigned int. Т.е. эта структура, судя по всему, будет состоять из одного юнита на 4 байта из которых только 8 бит юзаются под битовые поля.
[email protected] # 0 ⇈
bormand # 0 ⇈
guest # 0 ⇈
Чтобы первые пол года работать правильно, а потом выкинуть половину твоей программы в самый неожиданный момент
guest # 0
j123123 # 0 ⇈
У меня в контроллерах нет никакого понятия "root privileges", поэтому я за контроллеры.
guest # 0 ⇈
Fike # 0 ⇈
j123123 # 0 ⇈
https://www.bleepingcomputer.com/news/security/new-linux-sudo-flaw-lets-local-users-gain-root-privileges/
хотя подобные дыры наверняка еще будут.
bormand # 0 ⇈
Для guest6 что-то слишком свежая новость... Я думала, что он что-нибудь из 90х принёс.
[email protected] # 0 ⇈
ObeseYoung # 0 ⇈
guest # 0 ⇈
ObeseYoung # 0 ⇈