标签: bit-fields

位字段:设置与测试和设置(用于性能)

我有大量的C结构实例,如下所示:

struct mystruct
{
    /* ... */
    unsigned flag: 1;
    /* ... */
};
Run Code Online (Sandbox Code Playgroud)
  • flag 最初为0但在退出某个函数时必须为1.

最简单的实现是:

void set_flag(struct mystruct *sp)
{
    sp->flag = 1U;
}
Run Code Online (Sandbox Code Playgroud)

但是这样做对性能的影响可能是什么:

void set_flag(struct mystruct *sp)
{
    if (sp->flag == 0U)
    {
        sp->flag = 1U;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望避免写入主内存.第一个版本总是执行写操作,第二个版本只执行写操作(如果尚未设置标志),但在绝大多数情况下,标志将已设置.

还有哪些其他因素(例如分支预测)可能会影响性能?

到目前为止,我看到了一个小的速度增加,我希望随着数据集变大,这将变得更加重要.

是否有这种变化的风险使得大型数据集的程序变慢,如果是这样,在什么情况下会发生这种情况?

c optimization bit-fields

6
推荐指数
1
解决办法
1544
查看次数

如何在C程序中声明unsigned int

在这个链接上,我遇到了 http://lxr.linux.no/#linux+v2.6.36/include/linux/pci.h#L299 整数声明 unsigned int is_added:1;我已经制作了C程序并声明了整数,但在上面我看到了使用 :那 是什么语法?

c bit-fields

6
推荐指数
1
解决办法
7206
查看次数

为什么OpenCL中不允许使用位域?

OpenCL语言不支持位域.不支持他们的原因是什么?与其他忽略的部分(递归,函数指针,......)不同,有明显的理由不支持它们,我没有看到一个用于位域.我确信这不是代表委员会的疏忽,但是原因是什么?

(我存储了一些打包在int中的位,并且代码可以更好地与它们一起读取.我理解bitfields是一种很好的语法,可以避免位移和来回屏蔽,无论如何它们都是在汇编中转换的.)

opencl bit-fields

6
推荐指数
1
解决办法
1610
查看次数

在位字段的情况下,哪一个更好用,unsigned char或unsigned int以及为什么?

我只想知道以下结构声明.哪一个更适合用于内存分配?为什么?那么在unsigned char和unsigned int的情况下填充呢?

struct data{
 unsigned char a:3;
 unsigned char b:4;
}; 
Run Code Online (Sandbox Code Playgroud)

struct data{
 unsigned int a:3;
 unsigned int b:4;
};
Run Code Online (Sandbox Code Playgroud)

c linux structure bit-fields

6
推荐指数
2
解决办法
847
查看次数

位域元素的默认值

在C++ 11中,人们可以做到

struct S {int i = 42;};
Run Code Online (Sandbox Code Playgroud)

每当忘记初始化成员i时,它会默认初始化为42.我只是尝试使用bitfields作为

struct S {int i = 42    : 5;};
Run Code Online (Sandbox Code Playgroud)

而且我正在

错误:预期';' 在':'标记之前

对于位域成员是否存在此功能,如果存在,我该如何使用它?

c++ bit-fields c++11

6
推荐指数
2
解决办法
2466
查看次数

C++(不知何故)将struct限制为父联合大小

我正在尝试创建一个可变大小的颜色类 - 给定模板确定的值数组,我想为数组中的每个值创建命名别名,即:

template<int C = 3, typename T = unsigned char>
class Color {
public:
  union {
    T v[C];
    struct {
      T r, g, b, a;
    };
  };
};
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试为C = 3使用相同的类,则union要求4字节的大小('a'成员).或者,使用数学表达的位域大小((名为a,anonymous T成员的结构,大小在C> 3时评估为1),编译器发出一个允许警告(不可抑制,根据In gcc,如何静音 -敏感警告?),不适合大规模API的东西.

我如何允许单个类处理不同数量的变量,同时保留每个变量名称而不实现递归包含宏魔法(试过这个,不应该).提前致谢!

编辑:为了澄清问题,以下任何一个答案将解决此问题:

  • 抑制GCC的-perpermissive错误(忽略#pragma诊断不适用于许可)
  • 设置union或child struct的最大大小不超过C字节
  • 对于C字节未覆盖的成员,允许位域长度为0(GCC允许数据表达式用于位域长度,例如(C-3> 0)?8:0;)
  • 通过其他方式禁用C字节未涵盖的成员(即神话static_if())

c++ unions bit-fields

6
推荐指数
1
解决办法
364
查看次数

将uint32变量转换为位字段 - 未定义的行为?

我有一个由微控制器制造商提供的寄存器定义,可以作为位字段处理.寄存器定义如下:

#define SCU_WDTSCON0 (*( SCU_WDTSCON0_type *) 0xf00360f0u)
Run Code Online (Sandbox Code Playgroud)

位字段定义如下所示:

typedef volatile union {
unsigned U;
int I;
struct {
    unsigned    ENDINIT  :1;    // [0:0] End-of-Initialization Control Bit
    unsigned    LCK  :1;    // [1:1] Lock Bit to Control Access to WDTxCON0
    unsigned    HPW0     :2;    // [3:2] Hardware Password 0
    unsigned    HPW1     :4;    // [7:4] Hardware Password 1
    unsigned    PW   :8;    // [15:8] User-Definable Password Field for Access to WDTxCON0
    unsigned    REL  :16;   // [31:16] Reload Value for the WDT
  } B;
} SCU_WDTSCON0_type; …
Run Code Online (Sandbox Code Playgroud)

c embedded pointers bit-fields

6
推荐指数
1
解决办法
399
查看次数

C++在转换为较小类型时截断

我有一个64位长的int,其中包含一些位域.我需要在第二个和第三个字节中存储一个16位有符号的int并将其添加到32位值.我正在使用这样的东西:

u32 Function( s32 value , u64 bitfield )
{
    return value + (s16) (bitfield >> 8)
}
Run Code Online (Sandbox Code Playgroud)

我可以依赖编译器将位域转换为16位带符号的int,然后再将其扩展为32位带符号的int并执行添加吗?如果没有,我应该如何截断剩余的字节并执行我需要的类型转换?

c++ casting type-conversion bit-fields

6
推荐指数
1
解决办法
787
查看次数

使用与结构内部的位字段结合的正确语法

我有以下系列的结构.

struct FooWord1
{
    unsigned int Fill      :  8;
    unsigned int someData1 : 18;
    unsigned int someData2 : 6;
};

struct FooWord2
{
    unsigned int Fill      :  8;
    union
    {
        unsigned int A_Bit : 1;
        unsigned int B_Bit : 1;
    };
    unsigned int someData3 : 23;
};

struct Foo_Data
{
    FooWord1 fooWord1;
    FooWord2 fooWord2;
    FooWord3 fooWord3;  // similar to FooWord1
    FooWord4 fooWord4;  // similar to FooWord1
    FooWord5 fooWord5;  // similar to FooWord1
};

Foo_Data fooArray[SIZE];
Run Code Online (Sandbox Code Playgroud)

数据fooArray从网络消息逐字节复制.someData3如果我们不使用带有1位字段( …

c++ struct unions bit-fields

6
推荐指数
1
解决办法
556
查看次数

预C++ 20位字段零初始化

问题在下面的代码中,询问使用的值初始化语法是否意味着对于各个位字段成员是零初始化还是未初始化:

struct S { // S is POD
   int a : 3;
   int b : 1;
};

S s1;
S s2{};

s1.a; // uninitialized (ok, we understand this)
s1.b; //  "

s2.a; // zero or junk?
s2.b; //  "
Run Code Online (Sandbox Code Playgroud)

以下是位域的复习:https://en.cppreference.com/w/cpp/language/bit_field

为具有许多位字段的结构创建归零构造函数通常使用遗留代码中的丑陋memset来完成,因为在构造函数初始化列表中使用value-init语法重复每个位域成员的名称会产生无法管理的代码.即使结构是用于良好测量的POD,也可以完成此操作.想要在C++ 11中尽可能消除这种情况(不幸的是,默认成员初始化语法不适用于位字段,直到C++ 20).C++ 11是否使用{} -init语法保证对此进行零初始化?

c++ initialization language-lawyer bit-fields c++11

6
推荐指数
1
解决办法
302
查看次数