标签: bit-fields

在结构中表示小值的最有效方法是什么?

我经常发现自己必须代表一个由非常小的值组成的结构.例如,Foo有4个值a, b, c, d,范围从0 to 3.通常我不在乎,但有时,这些结构是

  1. 用于紧密循环;

  2. 他们的价值读数十亿次/秒,这是该计划瓶颈;

  3. 整个计划由数十亿美元组成Foo;

在这种情况下,我发现自己无法决定如何Foo有效地表达.我基本上有4种选择:

struct Foo {
    int a;
    int b;
    int c;
    int d;
};

struct Foo {
    char a;
    char b;
    char c;
    char d;
};

struct Foo {
    char abcd;
};

struct FourFoos {
    int abcd_abcd_abcd_abcd;
};
Run Code Online (Sandbox Code Playgroud)

它们分别使用128,32,8,8位Foo,从稀疏到密集.第一个例子可能是最语言的例子,但使用它实际上会增加16倍于程序的大小,这听起来不太合适.而且,大部分内存都会被零填充而根本不被使用,这让我想知道这不是浪费.另一方面,密集地打包它们会带来额外的开销来阅读它们.

在结构中表示小值的计算"最快"方法是什么?

c struct bit-fields

38
推荐指数
7
解决办法
2983
查看次数

如何确定/测量位域的结构大小?

#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
Run Code Online (Sandbox Code Playgroud)
  • int b:31,输出为8.
  • int b:1,输出为4.
  • int b:32,输出为12.

有人能解释一下这个原因吗?

c bit-fields

37
推荐指数
4
解决办法
3万
查看次数

在Swift中声明并使用位字段枚举

如何在Swift中声明和使用位字段?

声明这样的枚举确实有效,但尝试将OR 2值一起编译失败:

enum MyEnum: Int
{
    case One =      0x01
    case Two =      0x02
    case Four =     0x04
    case Eight =    0x08
}

// This works as expected
let m1: MyEnum = .One

// Compiler error: "Could not find an overload for '|' that accepts the supplied arguments"
let combined: MyEnum = MyEnum.One | MyEnum.Four
Run Code Online (Sandbox Code Playgroud)

我查看了Swift如何导入Foundation枚举类型,它通过定义struct符合RawOptionSet协议的方式来实现:

struct NSCalendarUnit : RawOptionSet {
    init(_ value: UInt)
    var value: UInt
    static var CalendarUnitEra: NSCalendarUnit { get }
    static …
Run Code Online (Sandbox Code Playgroud)

enums bit-fields swift

36
推荐指数
5
解决办法
3万
查看次数

带有bools的C++ bitfield打包

我刚刚用bitfields做了一个测试,结果令我感到惊讶.

class test1 {
public:
    bool test_a:1;
    bool test_b:1;
    bool test_c:1;
    bool test_d:1;
    bool test_e:1;
    bool test_f:1;
    bool test_g:1;
    bool test_h:1;
};

class test2 {
public:
    int test_a:1;
    int test_b:1;
    int test_c:1;
    int test_d:1;
    int test_e:1;
    int test_f:1;
    int test_g:1;
    int test_h:1;
};

class test3 {
public:
    int test_a:1;
    bool test_b:1;
    int test_c:1;
    bool test_d:1;
    int test_e:1;
    bool test_f:1;
    int test_g:1;
    bool test_h:1;
};
Run Code Online (Sandbox Code Playgroud)

结果如下: -

sizeof(test1) = 1   // This is what I'd expect. 8 bits in a byte …
Run Code Online (Sandbox Code Playgroud)

c++ bit-fields

30
推荐指数
4
解决办法
3万
查看次数

使用枚举类的C++ 11标准符合位掩码

您可以使用枚举类实现标准符合(如n3242草案的17.5.2.1.3所述)类型安全位掩码吗?我读它的方式,类型T是一个位掩码,如果它支持|,&,^,〜,| =,&=和^ =运算符,你还可以做if(l&r)其中l和r是T类型.列表中缺少的是运算符!=和==并允许排序一个也可能想要重载<.

让操作员工作只是烦人的样板代码,但我不知道如何(l&r).至少下面的代码不能用GCC编译(除了极其危险,因为它允许错误的隐式转换为int):

enum class Foo{
    operator bool(){
        return (unsigned)*this;
    }
};
Run Code Online (Sandbox Code Playgroud)

编辑:我现在肯定知道枚举类不能有成员.实际问题如果(l&r)仍然存在.

c++ bitmask bit-fields c++11 enum-class

30
推荐指数
3
解决办法
2万
查看次数

当int64_t更改为int32_t时,为什么类大小会增加

在我的第一个例子中,我使用了两个位域int64_t.当我编译并获得类的大小时,我得到8.

class Test
{
    int64_t first : 40;
    int64_t second : 24;
};

int main()
{
    std::cout << sizeof(Test); // 8
}
Run Code Online (Sandbox Code Playgroud)

但是,当我将第二个bitfeild更改int32_t为类的大小时,会增加到16:

class Test
{
    int64_t first : 40;
    int32_t second : 24;
};

int main()
{
    std::cout << sizeof(Test); // 16
}
Run Code Online (Sandbox Code Playgroud)

这种情况发生在GCC 5.3.0和MSVC 2015上.但为什么呢?

c++ memory-alignment memory-layout bit-fields object-layout

28
推荐指数
4
解决办法
2174
查看次数

在标志上使用按位运算符

我有四面旗帜

Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7
Run Code Online (Sandbox Code Playgroud)

假设我收到了两个标志Past和Future(setFlags(PAST | FUTURE)).我怎么知道它Past是否在里面?同样,我怎么能告诉它Current不在其中?这样我就不必测试每种可能的组合.

.net c# bit-manipulation bit-fields

26
推荐指数
5
解决办法
3万
查看次数

零长度位域的实际应用

我不完全确定C,但C++允许未命名的0字段位字段.例如:

struct X
{
    int : 0;
};
Run Code Online (Sandbox Code Playgroud)
  • 问题一:您能想到的实际用途是什么?
  • 问题二:你知道什么是现实世界的实际用途(如果有的话)?

在冰犯罪的回答之后编辑了这个例子

编辑:好的,多亏了目前的答案,我现在知道了理论目的.但问题是关于实际用途,所以他们仍然持有:)

c c++ bit-fields

26
推荐指数
4
解决办法
5242
查看次数

在字段中使用枚举是否安全?

说,我有以下结构:

typedef struct my_struct{
    unsigned long       a;
    unsigned long       b;
    char*               c;
    unsigned int        d1  :1;
    unsigned int        d2  :4;
    unsigned int        d3  :4;
    unsigned int        d4  :23;
} my_type, *p_type;
Run Code Online (Sandbox Code Playgroud)

该字段d3目前由直到#define达到的s 定义.0x000x0D

实际上,d3是一个枚举.所以很有可能继续前进并取而代之

    unsigned int        d3  :4;
Run Code Online (Sandbox Code Playgroud)

通过

    my_enum             d3  :4;
Run Code Online (Sandbox Code Playgroud)

这是安全/允许的吗?

代码必须用各种编译

  • 编译器(GCC,Visual Studio,嵌入式东西)
  • 平台(Win32,Linux,嵌入式东西)
  • 配置(编译为C,编译为C++)

显然,我可以保留d3原样的定义并在我的代码中使用枚举,将其分配给d3等等,但这不适用于C++.

c c++ enums bit-fields

26
推荐指数
3
解决办法
1万
查看次数

如何在Delphi记录中模拟位域?

我想在Delphi中声明一个包含与C中相同布局的记录.

对于那些感兴趣的人:此记录是Windows操作系统的LDT_ENTRY记录中的联合的一部分.(我需要在Delphi中使用此记录,因为我正在使用Delphi中的Xbox模拟器 - 请参阅sourceforge上的项目Dxbx).

无论如何,有问题的记录定义为:

    struct
    {
        DWORD   BaseMid : 8;
        DWORD   Type : 5;
        DWORD   Dpl : 2;
        DWORD   Pres : 1;
        DWORD   LimitHi : 4;
        DWORD   Sys : 1;
        DWORD   Reserved_0 : 1;
        DWORD   Default_Big : 1;
        DWORD   Granularity : 1;
        DWORD   BaseHi : 8;
    }
    Bits;
Run Code Online (Sandbox Code Playgroud)

据我所知,Delphi中没有可用的位域.我试过这个:

 Bits = record
      BaseMid: Byte; // 8 bits
      _Type: 0..31; // 5 bits
      Dpl: 0..3; // 2 bits
      Pres: Boolean; // 1 bit
      LimitHi: 0..15; // 4 bits
      Sys: Boolean; …
Run Code Online (Sandbox Code Playgroud)

delphi record bit-fields

25
推荐指数
3
解决办法
1万
查看次数