我可以始终假设 sizeof(GUID)==16 吗?
Windows header 中 GUID 的定义是这样的:
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
但是,没有定义任何打包。由于结构成员的对齐取决于编译器实现,因此我们可能会认为该结构的大小可能超过 16 个字节。
如果我可以假设它始终是 16 个字节 - 我使用 GUID 的代码会更加高效和简单。 但是,如果编译器出于某种原因在成员之间添加一些填充,那么这将是完全不安全的。
我的问题是否存在潜在原因?或者说 sizeof(GUID)!=16 实际上真的为 0 的情况的概率。
The definition of GUID in the windows header's is like this:
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
However, no packing is not defined. Since the alignment of structure members is dependent on the compiler implementation one could think this structure could be longer than 16 bytes in size.
If i can assume it is always 16 bytes - my code using GUIDs is more efficient and simple.
However, it would be completely unsafe - if a compiler adds some padding in between of the members for some reason.
My questions do potential reasons exist ? Or is the probability of the scenario that sizeof(GUID)!=16 actually really 0.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这不是官方文档,但也许是这篇文章可以减轻你的一些恐惧。我认为还有另一篇类似主题的文章,但我现在找不到了。
我想说的是,Windows 结构确实有一个打包说明符,但它是一个全局设置,位于头文件内的某个位置。它是
#pragma
之类的。而且它是强制性的,因为否则由不同编译器编译的程序无法相互交互,甚至无法与 Windows 本身交互。It's not official documentation, but perhaps this article can ease some of your fears. I think there was another one on a similar topic, but I cannot find it now.
What I want to say is that Windows structures do have a packing specifier, but it's a global setting which is somewhere inside the header files. It's a
#pragma
or something. And it is mandatory, because otherwise programs compiled by different compilers couldn't interact with each other - or even with Windows itself.它不是零,这取决于您的系统。如果对齐方式是基于单词(4 字节)的,则您将在
short
之间进行填充,并且大小将超过 16。如果您想确保它是 16 - 手动禁用填充,否则使用
sizeof
,并且不假设该值。It's not zero, it depends on your system. If the alignment is word (4-bytes) based, you'll have padding between the
short
s, and the size will be more than 16.If you want to be sure that it's 16 - manually disable the padding, otherwise use
sizeof
, and don't assume the value.如果我觉得需要做出这样的假设,我会在代码中添加“编译时断言”。这样,编译器就会让我知道我是否错误以及何时错误。
如果您已经或愿意使用 Boost,可以使用
BOOST_STATIC_ASSERT
宏来执行此操作。为了我自己的目的,我拼凑了我自己的(在 C 或 C++ 中与 MSVC、GCC 和一个或两个嵌入式编译器一起工作),它使用类似于本文中描述的技术:
获取编译时断言的真正技巧去工作cleanly 正在处理这样一个事实:某些编译器不喜欢与代码混合的声明(C 模式下的 MSVC),并且这些技术通常会生成警告,表明您不希望阻塞其他正常工作的构建。提出避免警告的技术有时是一个挑战。
If I feel I need to make an assumption like this, I'll put a 'compile time assertion' in the code. That way, the compiler will let me know if and when I'm wrong.
If you have or are willing to use Boost, there's a
BOOST_STATIC_ASSERT
macro that does this.For my own purposes, I've cobbled together my own (that works in C or C++ with MSVC, GCC and an embedded compiler or two) that uses techniques similar to those described in this article:
The real tricks to getting the compile time assertion to work cleanly is dealing with the fact that some compilers don't like declarations mixed with code (MSVC in C mode), and that the techniques often generate warnings that you'd rather not have clogging up an otherwise working build. Coming up with techniques that avoid the warnings is sometimes a challenge.
是的,在任何 Windows 编译器上。否则
IsEqualGUID
将不起作用:它比较仅前 16 个字节。同样,任何其他采用 GUID* 的 WinAPI 函数仅检查前 16 个字节。请注意,您不能为
windows.h
假定通用 C 或 C++ 规则。例如,尽管 ISO C 允许 9 位,但 Windows 上的字节始终为 8 位。Yes, on any Windows compiler. Otherwise
IsEqualGUID
would not work: it compares only the first 16 bytes. Similarly, any other WinAPI function that takes aGUID*
just checks the first 16 bytes.Note that you must not assume generic C or C++ rules for
windows.h
. For instance, a byte is always 8 bits on Windows, even though ISO C allows 9 bits.任何时候你根据别人结构的大小编写代码时,
警钟应该响起。
您能否举一个您想要使用的一些简化代码的示例?
如果需要结构的大小,大多数人只会使用 sizeof(GUID)。
话虽如此,我看不到 GUID 的大小会发生变化。
Anytime you write code dependent on the size of someone else's structure,
warning bells should go off.
Could you give an example of some of the simplified code you want to use?
Most people would just use sizeof(GUID) if the size of the structure was needed.
With that said -- I can't see the size of GUID ever changing.
得到 16。这对于了解是否需要在堆上手动分配非常有用。
Got 16. This is useful to know if you need to manually allocate on the heap.