Manipulacja na polu bitowym w C
Klasyczny problem testowania i ustawiania poszczególnych bitów w liczbie całkowitej w C jest prawdopodobnie jedną z najbardziej popularnych umiejętności programowania na poziomie średniozaawansowanym. Ustawiasz i testujesz proste maski bitowe, takie jak
<code>unsigned int mask = 1<<11; if (value & mask) {....} // Test for the bit value |= mask; // set the bit value &= ~mask; // clear the bit </code>
Naciekawy post na blogu twierdzi, że jest to podatne na błędy, trudne do utrzymania i złe praktyki. Sam język C zapewnia dostęp na poziomie bitowym, który jest bezpieczny i przenośny:
<code>typedef unsigned int boolean_t; #define FALSE 0 #define TRUE !FALSE typedef union { struct { boolean_t user:1; boolean_t zero:1; boolean_t force:1; int :28; /* unused */ boolean_t compat:1; /* bit 31 */ }; int raw; } flags_t; int create_object(flags_t flags) { boolean_t is_compat = flags.compat; if (is_compat) flags.force = FALSE; if (flags.force) { [...] } [...] } </code>
Ale to mnie zmuszawarować.
Ciekawy argument, jaki mieliśmy z moim współpracownikiem na ten temat, jest wciąż nierozwiązany. Oba style działają, a ja utrzymuję klasyczną metodę maski bitowej, która jest łatwa, bezpieczna i przejrzysta. Mój współpracownik zgadza się, że jest to powszechne i łatwe, ale metoda związkowa bitfielda jest warta kilku dodatkowych linii, aby była przenośna i bezpieczniejsza.
Czy jest więcej argumentów dla którejkolwiek ze stron? W szczególności, czy istnieje jakaś możliwa awaria, być może z endianizmem, której metoda maski bitowej może nie zostać wykonana, ale gdzie metoda struktury jest bezpieczna?