c - 带位域​​的打包结构的 Sizeof

标签 c sizeof bit-fields packed

考虑这段代码:

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

#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif

#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma(pack(push, 1)) __Declaration__ __pragma(pack(pop))
#endif

PACK(struct S
{
  uint8_t  f0;
  uint32_t f1;
  uint32_t f2 : 17;
});

int main()
{
    printf("%zu\n", sizeof(struct S));
    return 0;
}

没有给出编译器选项。

输出:

gcc   (9.2.0): 8
clang (8.0.1): 8
cl    (19.23.28106.4 for x86): 9

为什么cl的情况下sizeof的结果是9?

标准怎么说?

最佳答案

C 标准 C17 6.7.2.1/11 说,强调我的:

An implementation may allocate any addressable storage unit large enough to hold a bitfield. 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.

这些“存储单元”仅由编译器内部知晓,并且在不同的编译器上可以具有不同的大小。标准不支持位/字节“打包”的概念,并且不同编译器的行为也不同。

测试中使用的编译器均不违反 C 标准,因为这是 100% 实现定义的行为。

关于c - 带位域​​的打包结构的 Sizeof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60772586/

相关文章:

具有非连续布局的 C 位域元素

c - 读取位域元素时在 C 中给出不同的值

在位域上转换 uint64_t

c - 如何同时接受字符串输入?

c# - 为什么结构的 sizeof 是不安全的

c - 访问数组的特定元素

C语言计数器

c - 可变大小的二维数组声明错误吗?

c - 并发 tcp 客户端服务器程序和迭代程序有什么区别?

c - 在枚举中定义