标签: bit-fields

迭代位域的成员

我们有这样的例子:

struct X {
  int e0 : 6;
  int e1 : 6;
  int e2 : 6;
  ...
  int e10 : 6;
};

struct X c;
Run Code Online (Sandbox Code Playgroud)

如何“自动”访问成员,例如:
ce{0-10}?
假设我想读取 c.e0,然后 c.e1 ...
如果我的结构有 1000 个元素,我认为我不应该编写这么多代码,对吗?

你能帮我想一个解决方法、一个想法吗?
我提到我已经阅读了与此问题相关的其他帖子,但我没有找到解决方案。

非常感谢 !

c++ bit-fields

4
推荐指数
1
解决办法
2802
查看次数

用于从 H/W 寄存器读取的位字段

我想从32位寄存器中读取第2位、第5位和第6位。我决定使用结构位字段来存储它们。下面的数据结构正确吗?

struct readData
{
    int unwanted:1;
    int reqbit1:1;
    int unwanted1:2;
    int reqbit2:2;
    int unwanted2:26;
};
Run Code Online (Sandbox Code Playgroud)

我不确定如何创建位字段。我将使用一个 API 将字节从 h/w 寄存器直接复制到该结构。在这种情况下,reqbit1 会包含第 2 位吗?根据我的理解,编译器将第一位分配给 int 变量,第二位分配给另一个 int 变量,因此 reqbit1 不会从寄存器读取任何数据。下面的union不是更适合这种情况吗?

union readData
{
    struct readBits
    {
        bool unwanted:1;
        bool reqbit1:1;
        xxx unwanted1:2;
        short reqbit2:2;
        xxx unwanted2:26;
    };

    int regValue;
};
Run Code Online (Sandbox Code Playgroud)

如果这是正确的,我应该将unknown2声明为什么?

c bit-manipulation bitwise-operators unions bit-fields

4
推荐指数
1
解决办法
2233
查看次数

分配的数字太大而无法在位字段中表示未定义的行为

我有以下代码:

#include <stdio.h>
#include <stdint.h>

enum nums {
    ONE,
    TWO,
    TWENTY = 20
};

struct field {

    uint32_t something : 4;
    uint32_t rest : 28;
};

int main(void) {

    struct field f;
    f.something = TWENTY;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在运行 RTEMS 4.9.1 的 powerpc 8241 上,使用 minGW GCC 3.4.5(我知道它很旧)编译,此代码将导致段错误。我确定的原因是我们将一个数字设置为大,以便由相关位字段的位字段表示。由于我们有 4 位,它应该只能表示 0 -> 15,事实上,当我们用这些数字设置它时,它工作得很好。任何上面的东西都会崩溃。我无法在这里重现这种行为,所以我的问题是:

这是未定义的行为吗?如果是这样,交流标准中是否有涵盖它的参考文献?

或者它更可能只是因为我们非常旧的编译器而导致的错误?

c segmentation-fault undefined-behavior bit-fields

4
推荐指数
1
解决办法
679
查看次数

Bitfield 和 Union - C 中的意外结果

我在 C 课程中被分配了以下作业:

在此输入图像描述

我已经实现了解码8 字节长的 int 131809282883593 的分配,如下所示:

    #include  <stdio.h>
    #include <string.h>

    struct Message {
         unsigned int hour : 5;
         unsigned int minutes : 6;
         unsigned int seconds : 6;
         unsigned int day : 5;
         unsigned int month : 4;
         unsigned int year : 12;
         unsigned long long int code : 26;
    };  // 64 bit in total

    union Msgdecode {
        long long  int datablob;
        struct Message elems;
    };

    int main(void) {

        long long int datablob = 131809282883593;
        union …
Run Code Online (Sandbox Code Playgroud)

c unions bit-fields

4
推荐指数
1
解决办法
3329
查看次数

Bitfield Torrent 的混乱

我对bittorrent中的位字段消息有点困惑。我已经注意到下面问题形式的混乱。

  1. 可选与必需

握手序列完成后立即发送的位字段

我假设这是强制性的,即握手后必须遵循位字段消息。正确的?

  1. 什么时候需要位域?

位域消息只能在握手序列完成后、发送任何其他消息之前立即发送

假设我清楚地阅读了此消息,尽管它是可选消息。对等方仍然可以在任何消息(如请求、choke、uncoke 等)之前广播位字段消息。正确的 ?

  1. 第一个字节的高位对应片索引0

如果我是正确的,位字段代表状态,即对等方是否拥有给定的块。

假设我的位域是[1,1,1,1,1,1,1,1,1,1 ..]. 我确定对等点丢失了第 10 块,如果位字段看起来像这样,[1,1,0,1,1,1,1,1,1,1 ..]则对等点丢失了第 3 块。那么第一个字节的高位对应的片索引0意味着什么。

  1. 备用钻头

末尾的备用位设置为零

这是什么意思 ?我的意思是,如果末尾有一个位为 0,并不意味着同行将其作为缺失的部分。为什么使用备用位。

  1. 最重要的是位字段的用途是什么。

我对此的预感是,位字段可以更轻松地找到合适的对等点,以了解对等点可用的信息,但我对此是否正确?

@Encombe

这是我的位字段有效负载的样子

\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE

bittorrent bit-fields

4
推荐指数
1
解决办法
2334
查看次数

char 和 int 上的 C 结构位域之间的区别

当在 C 中使用位字段时,我发现了与用于声明字段的实际类型相关的意想不到的差异。

我没有找到任何明确的解释。现在,问题已经确定,因此,尽管没有明确的回应,但这篇文章可能对面临同样问题的任何人都有用。不过,如果有人能给出正式的解释,那就太好了。

以下结构在内存中占用 2 个字节。

struct {
  char field0 : 1; // 1 bit  - bit 0 
  char field1 : 2; // 2 bits - bits 2 down to 1
  char field2 ;    // 8 bits - bits 15 down to 8
} reg0;
Run Code Online (Sandbox Code Playgroud)

这个占用内存4个字节,问题是为什么?

struct {
  int  field0 : 1; // 1 bit  - bit 0 
  int  field1 : 2; // 2 bits - bits 2 down to 1
  char field2 ;    // 8 bits - bits …
Run Code Online (Sandbox Code Playgroud)

c struct sizeof bit bit-fields

4
推荐指数
1
解决办法
2765
查看次数

我应该使用位字段来映射传入的串行数据吗?

我们有通过串行(蓝牙)传入的数据,它映射到特定的结构。该结构的某些部分是子字节大小,因此“显而易见”的解决方案是将传入数据映射到位字段。我无法确定的是机器或编译器的位字节顺序是否会影响它(这很难测试),以及我是否应该完全放弃位字段。

例如,我们有一条1.5字节的数据,所以我们使用结构体:

{
    uint8_t data1; // lsb
    uint8_t data2:4; // msb
    uint8_t reserved:4;
} Data;
Run Code Online (Sandbox Code Playgroud)

保留位始终为 1

例如,如果传入的数据是 0xD2,0xF4,则值为 0x04D2,即 1234。

我们使用的结构始终适用于我们测试过的系统,但我们需要它尽可能可移植。

我的问题是:

  • data1无论字节序如何,总是会按预期表示正确的值(我假设是的,并且硬件/软件接口应该始终正确处理单个整个字节 - 如果发送 0xD2,则应该接收 0xD2)?

  • 是否可能data2reserved错误的方式,用data2代表高 4 位而不是低 4 位?

如果是:

  • 位字节顺序(通常)是否取决于字节字节顺序,或者它们可以完全不同吗?

  • 位字节顺序是由硬件还是编译器决定的?看起来 Intel 上的所有 Linux 系统都是一样的——对于 ARM 来说也是如此吗?(如果我们可以说我们可以支持所有 Intel 和 ARM linux 版本,那应该没问题)

  • 是否有一种简单的方法可以在编译器中确定它的方式,并在需要时保留位字段条目?

虽然位字段是映射传入数据的最简洁的代码方式,但我想我只是想知道放弃它们并使用类似的东西是否更安全:

struct {
    uint8_t data1; // lsb (0xFF)
    uint8_t data2; // msb (0x0F) & reserved (0xF0)
} Data;

Data d;

int value = (d.data2 & …
Run Code Online (Sandbox Code Playgroud)

c endianness bit-fields

4
推荐指数
1
解决办法
516
查看次数

C++20 中的位域初始化用`|| 新的 int` 结构

我遇到了关于 C++20 位字段初始化https://en.cppreference.com/w/cpp/language/bit_field#Cpp20_Default_member_initializers_for_bit_fields 的页面,其中对于 C++20 存在以下示例(此处简化):

struct S {
    int z : 1 || new int { 0 };
};
Run Code Online (Sandbox Code Playgroud)

该页面没有解释构造|| new int。这里有动态分配new int吗?的默认值z{0}多少,是吗?你能澄清一下吗?

c++ bit-fields c++20

4
推荐指数
1
解决办法
96
查看次数

避免多次读取或写入内存的易失性位域赋值表达式

我想使用易失性位字段结构来设置硬件寄存器,如以下代码

union foo {
    uint32_t value;
    struct {
        uint32_t x : 1;
        uint32_t y : 3;
        uint32_t z : 28;
    };
};
union foo f = {0};
int main()
{
    volatile union foo *f_ptr = &f;
    //union foo tmp;
    *f_ptr =  (union foo) {
        .x = 1,
        .y = 7,
        .z = 10,
    };
    //*f_ptr = tmp;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器会将其多次写入STRLDR HW 寄存器。可怕的是,当寄存器被写入时,它会立即触发硬件工作。

main:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed …
Run Code Online (Sandbox Code Playgroud)

c embedded assembly volatile bit-fields

4
推荐指数
1
解决办法
405
查看次数

位字段中宽度为零的连续未命名字段不会更改结构的大小

这里有一个struct

struct {
   unsigned int a : 8;
   unsigned int   : 0;
   unsigned int f : 1;
} A;
Run Code Online (Sandbox Code Playgroud)

sizeof这里的structA是8个字节。我明白那个。但现在如果我在接下来再放置一个宽度为零的未命名字段,如下所示,

struct {
   unsigned int a : 8;
   unsigned int   : 0;
   unsigned int   : 0;
   unsigned int f : 1;
} A;
Run Code Online (Sandbox Code Playgroud)

现在,sizeofstructA仍然是 8 个字节。当我看到引用时,它说使用未命名的字段宽度 0 强制下一个字段与下一个整数对齐。所以,这里的sizeof结构体A应该是 12 个字节。或者将两个连续的未命名字段宽度设置为 0 是否不会达到预期的效果?

c bit-fields

4
推荐指数
1
解决办法
61
查看次数