我需要以这种方式在一个字节中打包一些位:
struct
{
char bit0: 1;
char bit1: 1;
} a;
if( a.bit1 ) /* etc */
Run Code Online (Sandbox Code Playgroud)
要么:
if( a & 0x2 ) /* etc */
Run Code Online (Sandbox Code Playgroud)
从源代码的清晰度来看,对我来说很明显,bitfields更整洁.但哪个选项更快?我知道速度差异不会太大,如果有的话,但我可以使用其中任何一个,如果一个更快,更好.
另一方面,我已经读过,不保证位域不能跨平台排列相同的位,我希望我的代码可以移植.
注意:如果您打算回答"个人资料",我会,但是因为我很懒,如果有人已经有了答案,那就更好了.
代码可能有误,如果你愿意,可以纠正我,但请记住这个问题的重点是什么,请尝试回答.
位结构字段的最大位宽是多少?
struct i { long long i:127;}
Run Code Online (Sandbox Code Playgroud)
我可以在struct中定义一个位字段,位域大小最多为128位,或256位,或更大?有一些超宽的矢量类型,如sse2(128位),avx1/avx2(256位),avx-512(512位用于下一个Xeon Phis)寄存器; 以及gcc中的__int128等扩展名.
我正在使用Visual Studio 2008为Windows XP/Vista/7编写C++应用程序.我的一些结构使用位字段,如示例所示.
typedef struct myStruct_tag
{
BYTE myVar1;
WORD myVar2;
WORD myVar3;
union
{
struct
{
BYTE :1;
BYTE field1 :1;
BYTE field2 :1;
BYTE reserved :5;
} myBitField;
BYTE myVar4;
};
BYTE myVar5;
BYTE myVar6;
} myStruct_t;
Run Code Online (Sandbox Code Playgroud)
该领域的哪一端是最重要的位?
我可以相信每次访问位字段时C编译器都会模2 ^ n吗?或者是否有任何编译器/优化,如下所示的代码不会打印出溢出?
struct {
uint8_t foo:2;
} G;
G.foo = 3;
G.foo++;
if(G.foo == 0) {
printf("Overflow\n");
}
Run Code Online (Sandbox Code Playgroud)
先谢谢,弗洛里安
我在C标准草案(n1570)中看到了以下示例:
$ 3.14第4段:宣布为以下结构:
struct
{
char a;
int b:5, c:11, :0, d:8;
struct
{
int ee:8;
} e;
}
Run Code Online (Sandbox Code Playgroud)
那么,什么:0意思呢?
我知道什么是字段,但:0没有名字,我不明白.
:0没有任何标识符的目的是什么?
clang 6.0.0接受以下代码,但gcc 8.2拒绝
enum class E {
Good, Bad,
};
struct S {
E e : 2;
int dummy;
};
S f() {
return {E::Good, 100};
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会抱怨
错误:无法将'
{Good, 100}'从'<brace-enclosed initializer list>' 转换为'S'
哪一个是正确的?标准中哪里谈到这种情况?
让我们考虑以下计划test.c:
#include <stdio.h>
struct test {
unsigned int a:5;
};
int main () {
unsigned int i;
struct test t = {1};
for (i = 0; i < t.a << 1; i++)
printf("%u\n", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时gcc -Wsign-compare test.c生成以下警告(使用gcc 4.8.1测试):
test.c:9:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (i = 0; i < t.a << 1; i++)
^
Run Code Online (Sandbox Code Playgroud)
clang -Wsign-compare test.c 产生以下内容(使用clang 3.2进行测试):
test.c:9:19: warning: comparison of integers of different signs: 'unsigned …Run Code Online (Sandbox Code Playgroud) 关于位域声称位域是不可移植的各种问题我都遇到过很多评论,但是我从来没有能够找到解释其原因的来源.
从表面上看,我会假设所有的位域只是编译成相同的位移代码的变化,但显然必须有更多的,或者不会有这样的激烈不喜欢它们.
所以我的问题是什么使bitfields不可移植?
我有一个C++应用程序,包括许多具有手动控制位字段的结构,类似于
#define FLAG1 0x0001
#define FLAG2 0x0002
#define FLAG3 0x0004
class MyClass
{
'
'
unsigned Flags;
int IsFlag1Set() { return Flags & FLAG1; }
void SetFlag1Set() { Flags |= FLAG1; }
void ResetFlag1() { Flags &= 0xffffffff ^ FLAG1; }
'
'
};
Run Code Online (Sandbox Code Playgroud)
出于显而易见的原因,我想将其更改为使用位字段,例如
class MyClass
{
'
'
struct Flags
{
unsigned Flag1:1;
unsigned Flag2:1;
unsigned Flag3:1;
};
'
'
};
Run Code Online (Sandbox Code Playgroud)
我在进行此切换时遇到的一个问题是,我在此站点上遇到了许多引用,说明了C++中的位字段有多慢.我的假设是它们仍然比上面显示的手动代码更快,但是有没有任何硬参考资料涵盖在各种平台上使用位字段的速度影响,特别是32位和64位窗口.该应用程序处理内存中的大量数据,并且必须既快速又节省内存,这很可能就是为什么它首先以这种方式编写的.
我正在为二进制格式编写解析器.这种二进制格式涉及不同的表,这些表再次是二进制格式,通常包含不同的字段大小(大约在50到100之间).
这些结构中的大多数将具有位域,并且在用C表示时将看起来像这些:
struct myHeader
{
unsigned char fieldA : 3
unsigned char fieldB : 2;
unsigned char fieldC : 3;
unsigned short fieldD : 14;
unsigned char fieldE : 4
}
Run Code Online (Sandbox Code Playgroud)
我遇到了struct模块,但意识到它的最低分辨率是一个字节而不是一点,否则该模块几乎适合这项工作.
我知道使用ctypes支持位域,但我不知道如何在这里连接包含位域的ctypes结构.
我的另一个选择是自己操作这些位并将其提供给字节并将其与struct模块一起使用 - 但由于我有接近50-100种不同类型的此类结构,因此编写代码变得更容易出错.我也担心效率,因为这个工具可能用于解析大千兆字节的二进制数据.
谢谢.
bit-fields ×10
c ×6
c++ ×5
struct ×2
binary-data ×1
bit-shift ×1
c++11 ×1
c99 ×1
clang ×1
ctypes ×1
enum-class ×1
gcc ×1
overflow ×1
portability ×1
python ×1
structure ×1
windows ×1