【问题标题】:Clang and MSVC report different `sizeof` for the same structClang 和 MSVC 报告相同结构的不同 `sizeof`
【发布时间】:2017-02-18 10:46:30
【问题描述】:

Clang:3.8.0 MSVC:19.00.24215.1 用于 x64

什么可能导致编译器之间出现这种奇怪的差异? MSVC 报告 12,但 Clang 报告 8!这里的正确/预期行为是什么?标准对此有什么要说的吗?

enum class CodeCompletionDeclKind {};

struct SwiftSemanticToken {
  unsigned ByteOffset;
  unsigned Length : 24;
  CodeCompletionDeclKind Kind : 6;
  bool IsRef : 1;
  bool IsSystem : 1;
};
static_assert(sizeof(SwiftSemanticToken) == 8, "Too big");

int main()
{
    std::cout << "Hello, world!\n";
}

【问题讨论】:

  • 包含位域的结构的大小由实现定义。见注释部分:en.cppreference.com/w/cpp/language/bit_field 具体实现定义:“关于类对象中位域的实际分配细节的一切”
  • @RichardCritten:为什么不写答案而不是评论?
  • @ChristianHackl 正在打电话,格式化令人沮丧

标签: c++ visual-c++ clang language-lawyer sizeof


【解决方案1】:

包含位域的类对象的大小将由实现定义。

class.bit/1:

...类对象中位域的分配是 实现定义。位域的对齐是 实现定义。位域被打包成一些可寻址的 分配单位。 [ 注意: 位域跨越分配单元 一些机器,而不是其他机器。位域从右到左分配 在某些机器上,在其他机器上从左到右。 — 尾注 ]

【讨论】:

  • 谢谢,我会在一秒钟内接受你的回答,但首先:Clang 在这里做什么以使结构大小为 8。有没有办法(例如通过执行 unsigned ByteOffset : 1;)来强制 MSVC 使其成为 8 字节结构?我需要这种行为,因为它用于序列化
  • @HBellamy、Clang 和 GCC 显然足够聪明,可以跨 8 字节共享所有位字段成员。另一方面,MSVC 并没有把它们包装得那么紧。即使由于某些我不知道的原因被要求放弃对齐。正如here 所见,我只能将其设置为 9 字节。另请参阅this。根据 C++ 标准,编译器使用的任何大小都是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
相关资源
最近更新 更多