创建一个简单的便携式位掩码并使用它

时间:2014-01-10 17:14:01

标签: c++ c

这是我第一次尝试创建一个位掩码,虽然看似简单但我无法直观地看到所有内容。

请注意,我无法使用std::bitset

首先,我已经读过访问原始位是未定义的行为。 (因此使用char的并集会很糟糕,因为对于不同的编译器,这些位可能会被反转)。

我看过的大多数代码都使用结构来定义每个位,这种结构化数据的方式应该是独立于编译器的,因为第一位总是LSB。 (我假设)这是一个例子:

struct foo
{
    unsigned char a : 1;
    unsigned char b : 1;
    unsigned char unused : 6;
};

现在的问题是......你可以在结构中使用一个以上的变量并使它仍然与编辑器无关吗?似乎答案是肯定的,但我有一些奇怪的答案,并希望确定。类似的东西:

struct foo
{
    unsigned char ab : 2;
    unsigned char unused : 6;
};

似乎无论原始结构是否反转,从结构访问的第一位始终是LSB,因此您使用的位数无关紧要。

4 个答案:

答案 0 :(得分:1)

该行为不依赖于位顺序。您所编写的内容与语言标准相对应,因此在所有平台上的行为都相同。

答案 1 :(得分:1)

C标准没有指定单元内字段的顺序 - 在您的示例中,不能保证a在LSB中。如果你想要完全可移植的行为,你需要自己进行位操作,使用无符号整数类型,并且(如果使用大于一个字节的无符号整数类型),你需要担心从外部源读取/写入它们时的字节顺序。 / p>

答案 2 :(得分:1)

位域不能用于访问外部数据块中的特定位(如硬件寄存器或以字节流序列化的数据)。因此,位域在这种情况下没有用 - 至少对于可移植代码而言。

但如果您正在讨论在程序中使用位域而不是试图让它模拟一些外部位表示,那么它是100%可移植的。不是超级有用,但便携。

答案 3 :(得分:1)

我在C / C ++中花了很多时间,也许是因为这个问题,我从来没有看到过这样做过。我们总是使用无符号变量并对它们应用位掩码:

#define BITMASK_A  0x01
#define BITMASK_B  0x02

unsigned char bitfield;

然后,当您想要访问a时,使用(bitfield & BITMASK_A)

但是要回答你的问题,你的两个例子之间应该没有逻辑上的区别,如果编译器把ab放在低端,那么第一个例子也应该把一个放在LSb上。