位操作的良好做法 [英] Bit manipulations good practices

查看:67
本文介绍了位操作的良好做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一名初学者C程序员,我想知道,什么是在设备中设置控制位的最佳易读和易懂的解决方案.有什么标准吗?有没有可以模仿的示例代码? Google没有给出可靠的答案.

As a beginner C programmer, I am wondering, what would be the best easy-to-read and easy-to-understand solution for setting control bits in a device. Are there any standards? Any example code to mimic? Google didn't give any reliable answer.

例如,我有一个控制块图:

For example, I have a control block map:

我看到的第一种方法是简单地设置所需的位.它需要在注释中进行一堆解释,而且似乎还不是那么专业.

The first way I see would be to simply set the needed bits. It requires a bunch of explanations in comments and seems to be not all that professional.

DMA_base_ptr[DMA_CONTROL_OFFS] = 0b10001100;

我看到的第二种方法是创建一个位字段.我不确定是否应该坚持使用它,因为我从未遇到过以这种方式使用它的情况(与我提到的第一个选项不同).

The second way I see is to create a bit field. I'm not sure if this is the one should I stick to, since I never encountered it being used in such way (unlike the first option I mentioned).

struct DMA_control_block_struct
{ 
    unsigned int BYTE:1; 
    unsigned int HW:1; 
    // etc
} DMA_control_block_struct;

其中一种选择是否比另一种更好?有什么我看不到的选择吗?

Is one of the options better than the other one? Are there any options I just don't see?

任何建议将不胜感激

推荐答案

位字段的问题是C标准并未规定定义它们的顺序与实现它们的顺序相同.因此,您可能没有设置自己认为的位.

The problem with bit fields is that the C standard does not dictate that the order in which they are defined is the same as the order that they are implemented. So you may not be setting the bits you think you are.

C标准的第6.7.2.1p11部分声明:

一个实现可以分配任何大的可寻址存储单元 足以容纳一个位域.如果还有足够的空间,则位域 紧跟在结构中另一个位域之后的是 打包到同一单元的相邻位中. 如果空间不足 保留,是否放入不适合的位域 下一个单位或与相邻单位重叠的是 实现定义的.内位域的分配顺序 一个单位(高阶到低阶或低阶到高阶)是 实施定义.可寻址存储的对齐方式 未指定单位.

An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

例如,从Linux上的/usr/include/netinet/ip.h文件文件中查看struct iphdr的定义,该定义代表IP头:

As an example, look at the definition of struct iphdr, which represents an IP header, from the /usr/include/netinet/ip.h file file on Linux:

struct iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
    u_int8_t tos;
    ...

您可以在此处看到,根据实现的不同,位域的放置顺序也不同.您也不应使用此特定检查,因为此行为取决于系统.该文件是系统的一部分,因此可以接受.其他系统可能以不同的方式实现这一目标.

You can see here that the bitfields are placed in a different order depending on the implementation. You also shouldn't use this specific check because this behavior is system dependent. It is acceptable for this file because it is part of the system. Other systems may implement this in different ways.

所以不要使用位域.

执行此操作的最佳方法是设置所需的位.但是,为每个位定义命名常量并对要设置的常量执行按位或"运算将很有意义.例如:

The best way to do this is to set the required bits. However, it would make sense to define named constants for each bit and to perform a bitwise OR of the constants you want to set. For example:

const uint8_t BIT_BYTE =     0x1;
const uint8_t BIT_HW   =     0x2;
const uint8_t BIT_WORD =     0x4;
const uint8_t BIT_GO   =     0x8;
const uint8_t BIT_I_EN =     0x10;
const uint8_t BIT_REEN =     0x20;
const uint8_t BIT_WEEN =     0x40;
const uint8_t BIT_LEEN =     0x80;

DMA_base_ptr[DMA_CONTROL_OFFS] = BIT_LEEN | BIT_GO | BIT_WORD;

这篇关于位操作的良好做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆