【发布时间】:2013-10-11 03:07:02
【问题描述】:
MSDN 明确声明
对于所有其他类型,包括结构,sizeof 运算符只能 在不安全的代码块中使用。
C# Language Specification 更加精确:
- 未指定将成员打包到结构中的顺序。
- 出于对齐目的,开头可能有未命名的填充 结构体、结构体内部和结构体末尾。
- 用作填充的位的内容是不确定的。
- 当应用于具有结构类型的操作数时,结果是该类型变量中的总字节数,包括任何填充。
但是 CLR 将如何处理以下结构:
[StructLayout(LayoutKind.Explicit, Size = 1, Pack = 1)]
public struct MyStruct
{
[FieldOffset(0)] public byte aByte;
}
public struct MyEmptyStruct { }
在MyStruct 中,我们通过StructLayout 属性显式地强制布局、大小以及如何打包它。此结构假定在内存中的大小为 1 个字节。
另一方面,MyEmptyStruct 是空的,我们可以假设内存中的大小为 0 字节 - 即使这样的结构很可能不会被使用,它仍然是一个有趣的案例。
当尝试使用sizeof(MyStruct) 和sizeof(MyEmptyStruct) 计算这些结构的大小时,编译器会抛出以下错误:
'*' 没有预定义的大小,因此 sizeof 只能 在不安全的环境中使用
我想知道为什么在这种情况下使用sizeof 被认为是unsafe。该问题并非旨在寻求解决方法或正确方法来计算结构的大小,而是关注原因。
【问题讨论】:
-
Skeet 的回答在这里:sizeof() structures not known. Why? 很好。
-
我没有看到任何地方为什么它是
unsafe。我猜编译器需要它来强化sizeof(struct)将根据x86/x64 设置等而变化的概念,所以这是一件不安全的事情。但是仅仅询问结构的大小不是unsafe,就像获取和使用指向内存块的指针是unsafe一样。 -
投票重新开放。这不是与上面链接的问题的重复 - 另一个问题询问为什么您不能获得仅包含内置类型的
struct的大小,而不是为什么 @ 的sizeof987654339@s 在托管上下文中不可用。 -
原因在 Chris Brummes 博客文章的第一句话中概述了:blogs.msdn.com/b/cbrumme/archive/2003/04/15/51326.aspx - “我们不公开对象的托管大小,因为我们希望保留改变我们放置方式的能力这些东西都出来了。”
-
我得出的结论是,您需要
unsafe的原因是唯一的原因您可能不得不使用sizeof()来获取结构的大小如果您要进行指针运算,因此将使用限制为unsafe上下文是明智的。请注意,序列化数据时不能使用sizeof(struct),因为它的大小可能与Marshal.Sizeof()不同