【问题标题】:Why is "unsigned" mapped to a 32 bits in MSVC C++?为什么“无符号”映射到 MSVC C++ 中的 32 位?
【发布时间】:2014-03-27 10:34:39
【问题描述】:

我在 MSVC++ 2008 中定义了以下结构:

struct{
 Uint16  XDD;
 unsigned XDD_UI:8;
 unsigned XDD_CR:8;
}byte;

当对上述结构执行 sizeof 时,它表明 unsigned 使用 32 位来存储数据。

  • 为什么会这样,它与内存对齐有关吗?
  • 我怎么能强制编译器只使用没有定义的 8 位 触摸结构定义?

【问题讨论】:

标签: c++ visual-c++ visual-studio-2008 struct unsigned


【解决方案1】:

当您编写 unsigned 时,它是 unsigned int 的缩写,在 Windows 上是 32 位宽。这意味着它具有4 的对齐方式。由于你的结构是对齐的,XDDXDD_UI 之间有两个字节填充,结构末尾有两个字节填充。

你的结构是这样布局的:

0-1 XDD 2-3 4-4 XDD_UI 5-5 XDD_CR 6-7

如果你想打包结构,那么你需要打包它。使用#pragma pack 来实现这一点。但是,即使您这样做,编译器也会生成一个大小为 6 的结构。这是因为位域被打包到 unsigned int 中,因此您的两个位域将始终占用 4 个字节。

如果您确保将位域声明为大小不超过 2 个字节的类型,那么您的结构将是 4 个字节。这对于对齐的结构来说是正确的。例如,这个结构的大小为 4。

struct s {
    unsigned short XDD;
    unsigned short XDD_UI:8;
    unsigned short XDD_CR:8;
};

但是,在我看来,声明没有位域的结构更明智:

struct s {
    Uint16 XDD;
    unsigned char XDD_UI;
    unsigned char XDD_CR;
};

您可以声明该结构对齐并具有您想要的布局。

【讨论】:

  • 是否有任何有用的程序可以保证在任何符合 C 标准规定的规则下工作,如果位域可以以编译器认为合适的任何方式分配,则不能保证工作?我了解规则是什么,但我很好奇为什么不允许编译器例如提供一种将四个 6 位字段打包成 3 字节结构的方法,前提是硬件可以处理得当。
【解决方案2】:
And how could I force the compiler to use only 8 bits as defined without touching the struct definition 

使用#pragma

#pragma pack(1)
struct{
 Uint16  XDD;
 unsigned XDD_UI:8;
 unsigned XDD_CR:8;
}byte;
#pragma pack()

【讨论】:

  • 使用#pragma pack(1) 结构体的大小仍然比预期的要大。
【解决方案3】:

取决于编译器和机器无符号也可能是 64 位。由于以前的处理器是 32 位的,因此将 32 位用于 int 已成为普遍规范。但是我们不应该总是依赖 int 或 unsigned 来确定它的范围。

char 或 unsgined char 肯定会使用 8 位。但是内部编译器可能已经对其进行了调整,将其用作 4 字节进行处理。

【讨论】:

  • 不,char至少 8 位,就像unsigned至少 16 位。
  • 但在 C 语言中 sizeof char 始终为 1
  • 是的,但 CHAR_BIT 并不总是 8。
猜你喜欢
  • 2017-10-07
  • 2011-08-31
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
相关资源
最近更新 更多