可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Let's say I have a C structure defined as
struct data { /* some memebers */ int flag_a:1; int flag_b:1; int flag_c:1; /* some other members */ }
Is there a way to take advantage of the bitfields being represented as a single int in memory and write the condition s.flag_a | s.flag_b | s.flag_c
as a simpler expression such as s.flags
?
Or would a smart compiler such as GCC be able to actually deduce it?
Edit: To make myself absolutely clear: I'm looking for a portable way to test for all the flags being set without explicitly testing each of the flags separately.
回答1:
This isn't possible to do portably, in any deterministic way. The problem is that the C standard does not guarantee anything about those bits: you can't know which bit that is the LSB nor can you know if there is padding. On top of that, endianess is also an issue. (And in theory, different signedness formats.) See this for details.
In theory you could create a union between this bit field and one with : 3
bits, but the result of such practice will not be predictable nor well-defined.
The best solution is to get rid of the bit-field and replace it with a deterministic, 100% portable solution:
typedef struct { uint8_t flags; } data_t #define FLAG_A 0x01u #define FLAG_B 0x02u #define FLAG_C 0x04u #define FLAG_ALL (FLAG_A | FLAG_B | FLAG_C) data_t data = { .flags = FLAG_A | FLAG_B | FLAG_C}; if(data.flags & FLAG_ALL) ...
回答2:
Bit field use is entirely non-portable. You can't be sure where each field is in the underlying structure. Per 6.7.2.1 Structure and union specifiers, paragraph 11 of the C Standard:
An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.