12

我有一个代码,它使用如下声明的位域

typedef struct my{
    const char *name;
    uint8_t is_alpha : 1;   
    uint8_t is_hwaccel : 1; 
    uint8_t x_chroma_shift; 
    uint8_t y_chroma_shift; 

} mystr; 

uint8_t类型定义为unsigned char.

使用此位字段在 MS-VS 2008 中构建代码会给出如下警告:

imgconvert.c(60):警告 C4214:使用了非标准扩展:int 以外的位字段类型。
  1. 使用非 int 类型的位字段是否有任何问题/潜在问题?为什么要发出警告?
  2. 除了 C99 C 语言规范允许的 int 类型位文件吗?
4

3 回答 3

6

1] 使用非 int 类型的位字段是否有任何问题/潜在问题?为什么要发出警告?

由于位字段是低级的,如果您使用非标准类型,则可能存在可移植性问题。因此警告 - 请注意它仍然是警告而不是错误。

2] C99 C 语言规范是否允许除了 int 类型的位字段?

来自 C99 的草案:

6.7.2.1 结构和联合说明符

4 位域的类型应为 _Bool、signed int、unsigned int 或其他一些实现定义的类型的合格或不合格版本。

于 2010-02-17T12:28:42.517 回答
2

为什么不使用int?位域的实际实现因编译器而异。如果要编写可移植代码,请使用int. 如果你想创建一个小结构,或者一个固定字节数的结构,或者一个位在固定位置的结构,不要使用位域。创建一个uint8_t名为 like 的成员flags并定义宏以用作位掩码。

于 2010-02-17T16:47:23.687 回答
0

正如其他人提到的可移植性问题等,如果您不知道可以通过警告编译指示禁用警告:
https ://docs.microsoft.com/en-us/cpp/preprocessor/warning?view=vs -2019

#pragma warning(push)
#pragma warning(disable: 4214) // warning C4214: nonstandard extension used: bit field types other than int
typedef struct my{
    const char *name;
    uint8_t is_alpha : 1;   
    uint8_t is_hwaccel : 1; 
    uint8_t x_chroma_shift; 
    uint8_t y_chroma_shift; 
} mystr; 
#pragma warning(pop)

您还可以在项目属性中禁用特定警告,但它们是项目范围的。这样您就可以按数据类型控制它们。

然后,如果您不确定 100% MSVC 将为这些生成什么样的二进制代码,请在调试器中运行它并查看“反汇编视图”(在它被访问的位置中断),或者加载您的可执行文件(使用 PDB符号文件)在 IDA Pro、Ghidra 等反汇编程序中。

于 2019-11-05T20:39:10.340 回答