标签: bit-fields

如何获取位域以正确的顺序排列我的位?

首先,相关应用程序始终位于同一处理器上,并且编译器始终为 gcc,因此我不担心位域不可移植。

gcc 布局位字段,使得第一个列出的字段对应于字节的最低有效位。因此,在以下结构中,a = 0,b = 1,c = 1,d = 1,您将得到一个字节值 e0。

struct Bits {
  unsigned int a:5;
  unsigned int b:1;
  unsigned int c:1;
  unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)

(实际上,这是C++,所以我说的是g++。)

现在假设我希望a是一个六位整数。

现在,我明白为什么这不起作用,但我编写了以下结构:

struct Bits2 {
  unsigned int a:6;
  unsigned int b:1;
  unsigned int c:1;
  unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)

将bcd设置为 1,将a设置为 0 会产生以下两个字节:

c0 01
Run Code Online (Sandbox Code Playgroud)

这不是我想要的。我希望看到这个:

e0 00
Run Code Online (Sandbox Code Playgroud)

有没有办法指定一个结构,该结构在第一个字节的最高有效位中具有三位,并且在第一个字节的五个最低有效位和第二个字节的最高有效位中具有六个位?

请注意,我无法控制这些位的布局位置:它是由其他人的接口定义的位布局。

c c++ gcc bit-fields

5
推荐指数
1
解决办法
5440
查看次数

包含位字段的结构的大小

可能重复:
为什么structof sizeof不等于每个成员的sizeof之和?

我试图理解位域的概念.但我无法找到CASE III中以下结构的大小为8字节的原因.

案例I:

struct B    
{
    unsigned char c;  // +8 bits
} b;
Run Code Online (Sandbox Code Playgroud)

的sizeof(B); //输出:1(因为unsigned char在我的系统上占用1个字节)

案例II:

struct B
{
    unsigned b: 1;
} b;

 sizeof(b); // Output: 4 (because unsigned takes 4 bytes on my system)
Run Code Online (Sandbox Code Playgroud)

案例III:

struct B
{
    unsigned char c;  // +8 bits
    unsigned b: 1;    // +1 bit
} b;

sizeof(b); // Output: 8 
Run Code Online (Sandbox Code Playgroud)

我不明白为什么案例III的输出为8.我期待1(char)+ 4(无符号)= 5.

c c++ sizeof bit-fields structure-packing

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

位域的完美转发解决方法

我正在寻找模板重载解析中位域的解决方法。

我有一个函数模板,用于完美转发其参数:

template <typename... Args> void f(Args &&...args) { }
Run Code Online (Sandbox Code Playgroud)

如果我尝试将它与位域参数一起使用,如下所示:

struct bits { unsigned int foo:1; };
bits b{1};
f(b.foo);
Run Code Online (Sandbox Code Playgroud)

...它无法编译:

main.cpp:26:7: 错误:非常量引用无法绑定到位字段“foo”
    f(b.foo);
      ^~~~~

有没有办法重载f(),使其按值获取位字段,但在常见情况下仍按引用获取其他参数?

到目前为止我还做不到。例如,如果我添加一个按值接受参数的重载......

main.cpp:27:5: 错误:对“f”的调用不明确
    f(b.foo);
    ^

c++ templates bit-fields perfect-forwarding c++11

5
推荐指数
1
解决办法
1559
查看次数

C++子结构位域大小

考虑以下:

class A { public:
    int     gate_type :  4;
    bool storage_elem :  1;
    uint8_t privilege :  2;
    bool      present :  1;
} __attribute__((packed));

class B { public:
    struct Sub {
        int     gate_type :  4;
        bool storage_elem :  1;
        uint8_t privilege :  2;
        bool      present :  1;
    } type_attr; //Also tried with "__attribute__((packed))" here in addition to outside
} __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)

编译器是g ++ 4.8.1.sizeof(A)== 1,sizeof(B)== 4.为什么会这样?我需要像结构B这样的东西,大小为1.

c++ bit-fields

5
推荐指数
1
解决办法
306
查看次数

如何在 Swift 中使用位字段来存储超过 1 位的值

C我可以做这样的事情:

struct byte_nibbles {
    unsigned char b1: 4;
    unsigned char b2: 4;
    unsigned char b3: 4;
    unsigned char b4: 4;
    unsigned char b5: 4;
    unsigned char b6: 4;
    unsigned char b7: 4;
    unsigned char b8: 4;
};

union {
    unsigned long var;
    struct byte_nibbles b;
}
u;

int main(void)
{
    u.b.b1=0x01; u.b.b2=0x02; u.b.b3=0x03; u.b.b4=0x04;
    u.b.b5=0x05; u.b.b6=0x06; u.b.b7=0x07; u.b.b8=0x08;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以我可以访问 byte_nibbles 的特定部分。显然这只是一个例子。可以创建适合基本类型的任何大小的位域。

尽管我付出了努力并进行了大量研究,但我无法弄清楚如何在Swift 中做到这一点。我可以使用按位获得相同的结果,但这不是那么可读和优雅。

任何的想法?

struct bit-fields swift

5
推荐指数
1
解决办法
1598
查看次数

如何将有符号整数转换为 15 位位字段?

我有一些位域:

int somefield : 15;
Run Code Online (Sandbox Code Playgroud)

我正在尝试将 int 转换为 15 位(可以是正数或负数)。

有效执行此操作的最佳做​​法是什么?

c bit-fields

5
推荐指数
1
解决办法
2555
查看次数

位字段成员的类型

从理论上讲,我们有两种选择来选择位字段成员的类型:

  1. 基础类型的类型.
  2. 比特数适合的最小类型.

那么实际上是什么类型的位域成员(我在标准中找不到迄今为止的提示--C和C++一样)并且C和C++之间有什么区别?

虽然知道特定的编译器不是引用,但我试图通过C++函数重载和typeid运算符获得至少一些提示:

#include <typeinfo>
struct S
{
    unsigned int n4  :  4;
    unsigned int n12 : 12;
};

void f(unsigned char)
{
    std::cout << "uc" << std::endl;
}

void f(unsigned short)
{
    std::cout << "us" << std::endl;
}

void f(unsigned int)
{
    std::cout << "ui" << std::endl;
}

int main(int argc, char* argv[])
{
    S s; s.n4 = 0; s.n12 = 0;
    f(s.n4);
    f(s.n12);
    std::cout << typeid(s.n4).name() << std::endl;
    std::cout << typeid(s.n12).name() << std::endl;
    std::cout << typeid(unsigned …
Run Code Online (Sandbox Code Playgroud)

c c++ bit-fields

5
推荐指数
1
解决办法
651
查看次数

成员结构位域元素的初始化列表初始化导致 IAR ARM 中的错误

我在 IAR 中有以下类结构:

class A
{
public:
    A(){}
    virtual ~A() {};
    virtual void load() {};
};


class C
{
public:
    C()
    {
        //C does other stuff, not relevant
    }
};

class D;

class B : public A
{
public:
    B() : invert(false) {};
    virtual ~B() {};
    void load()
    {
        //Irrelevant stuff done here
    }
private:
    C member_c;
    std::vector<D*> vector_of_d;
    struct {
        bool var_1:1;
        bool var_2:1;
        bool var_3:1;
        bool var_4:1;
        bool invert:1;
    };
};
Run Code Online (Sandbox Code Playgroud)

我遇到了为初始化 B 而生成的程序集的错误,它似乎对 VTable 指针的位置与匿名结构位域的位置感到“困惑”。当它设置反转位为假时,它转到对象的第一个字(即 VTable 指针)并翻转地址中的一个位。当我稍后调用 …

c++ arm vtable iar bit-fields

5
推荐指数
1
解决办法
261
查看次数

Rust位域和枚举C++风格

我是一个来自C/C++的Rust初学者.首先,我尝试使用user32.MessageBox为Microsoft Windows创建一个简单的"Hello-World"程序,我偶然发现了与bitfields相关的问题.免责声明:所有代码段都是在SO编辑器中编写的,可能包含错误.

消息框中的"Hello-World"

调用该函数的UTF-16LE版本所需的合并C声明是:

enum MessageBoxResult {
    IDFAILED,
    IDOK,
    IDCANCEL,
    IDABORT,
    IDRETRY,
    IDIGNORE,
    IDYES,
    IDNO,
    IDTRYAGAIN = 10,
    IDCONTINUE
};

enum MessageBoxType {
    // Normal enumeration values.
    MB_OK,
    MB_OKCANCEL,
    MB_ABORTRETRYIGNORE,
    MB_YESNOCANCEL,
    MB_YESNO,
    MB_RETRYCANCEL,
    MB_CANCELTRYCONTINUE,

    MB_ICONERROR            = 0x10UL,
    MB_ICONQUESTION         = 0x20UL,
    MB_ICONEXCLAMATION      = 0x30UL,
    MB_ICONINFORMATION      = 0x40UL,

    MB_DEFBUTTON1           = 0x000UL,
    MB_DEFBUTTON2           = 0x100UL,
    MB_DEFBUTTON3           = 0x200UL,
    MB_DEFBUTTON4           = 0x300UL,

    MB_APPLMODAL            = 0x0000UL,
    MB_SYSTEMMODAL          = 0x1000UL,
    MB_TASKMODAL            = 0x2000UL,

    // Flag values.
    MB_HELP                 = 1UL << 14,

    MB_SETFOREGROUND        = …
Run Code Online (Sandbox Code Playgroud)

c++ winapi bitflags rust bit-fields

5
推荐指数
1
解决办法
406
查看次数

c++ - 如何在C++编译时检测结构的成员是否为位域?

给定一个结构 S:

struct S {
  bool a : 1;
  bool b : 1;
};
Run Code Online (Sandbox Code Playgroud)

如何确定S::aS::b是在编译时位字段?

我试图提出一个类似的宏,IsBitField(S, a)但很难将 SFINAE 应用到offsetof()addressof()(众所周知,每个位域的操作都是无效的)。

c++ sfinae type-traits bit-fields

5
推荐指数
1
解决办法
135
查看次数