在窗口标题中的GUID的定义是这样的:
typedef struct _GUID { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[ 8 ]; } GUID;
但是,没有包装没有定义。 由于结构成员的alignment取决于编译器的实现,人们可能会认为这个结构的长度可能会超过16个字节。
如果我可以假设它总是16个字节 – 我的代码使用GUID更高效和简单。 然而,这将是完全不安全的 – 如果编译器由于某种原因在成员之间添加了一些填充。
我的问题是否存在潜在的原因? 或者是sizeof(GUID)!= 16实际上为0的情况的概率。
这不是官方文件,但也许这篇文章可以减轻你的一些恐惧。 我觉得还有一个类似的话题,但我现在找不到。
我想说的是,Windows结构确实有一个打包说明符,但它是一个全局设置,这是在头文件内的某个地方。 这是一个#pragma
什么的。 这是强制性的,因为否则由不同的编译器编译的程序不能相互交互 – 甚至不能与Windows本身交互。
这不是零,这取决于你的系统。 如果对齐方式是基于单词(4字节)的,则在short
之间填充,大小将超过16。
如果你想确保它是16 – 手动禁用填充,否则使用sizeof
,并且不要假设值。
如果我觉得我需要这样做,我会在代码中加入一个“编译时间断言”。 这样,编译器会让我知道,如果我错了。
如果你有或者愿意使用Boost,那么有一个BOOST_STATIC_ASSERT
宏来做这件事。
为了我自己的目的,我用自己的方法(使用MSVC,GCC和一个或两个嵌入式编译器工作在C或C ++中)使用与本文中描述的技术类似的技术:
让编译时间断言干净地工作的真正技巧是处理这样的事实,即一些编译器不喜欢与代码混合的声明(C模式下的MSVC),并且这些技术经常产生警告,而您不希望发生堵塞在其他方面工作的构建。 避免警告的技术有时是一个挑战。
任何时候,如果您根据别人的结构编写代码,警告响铃应该熄灭。
你能举一个你想使用的简化代码的例子吗? 如果需要结构的大小,大多数人只会使用sizeof(GUID)。
这就是说 – 我看不到GUID的大小不断变化。
是的,在任何Windows编译器上。 否则IsEqualGUID
将不起作用:它仅比较前16个字节。 同样,任何其他WinAPI函数采用一个GUID*
只是检查前16个字节。
请注意,您不能为windows.h
通用的C或C ++规则。 例如,Windows上的字节总是8位,即使ISO C允许9位。
#include <stdio.h> #include <rpc.h> int main () { GUID myGUID; printf("size of GUID is %d\n", sizeof(myGUID)); return 0; }
得到了16.这是有用的知道,如果你需要手动分配在堆上。