windows头文件中GUID的定义如下:
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
但是,没有定义打包。由于结构成员的对齐依赖于编译器实现,因此可以认为该结构的大小可能大于16字节。
如果我可以假设它总是16字节-我的代码使用guid更有效和简单。但是,如果编译器出于某种原因在成员之间添加了一些填充,那么这将是完全不安全的。
我的问题是否存在潜在的原因?或者是出现sizeof(GUID)!
这不是官方文档,但也许本文可以减轻您的一些担忧。我想还有一篇类似的文章,但是我现在找不到。
我想说的是,Windows结构确实有一个打包说明符,但它是一个全局设置,在头文件的某个地方。它是#pragma
之类的。而且它是强制性的,否则由不同的编译器编译的程序就不能相互交互——甚至不能与Windows本身交互。
它不是零,这取决于你的系统。如果对齐方式是基于字(4字节)的,那么在short
之间将有填充,并且大小将大于16。
如果你想确保它是16 -手动禁用填充,否则使用sizeof
,不假设值
如果我觉得我需要做出这样的假设,我将在代码中添加一个'编译时断言'。这样,当我错了,编译器会告诉我。
如果你有或愿意使用Boost,有一个BOOST_STATIC_ASSERT
宏可以做到这一点。
出于我自己的目的,我拼凑了我自己的(在C或c++中使用MSVC、GCC和一两个嵌入式编译器),使用与本文中描述的技术类似的技术:
- http://www.pixelbeat.org/programming/gcc/static_assert.html
使编译时断言干净地工作的真正技巧是处理一些编译器不喜欢声明与代码混合的事实(C模式下的MSVC),并且这些技术经常生成警告,您不希望这些警告阻塞其他正常工作的构建。想办法避免这些警告有时是一个挑战。
可以,在任何Windows编译器上都可以。否则IsEqualGUID
将不起作用:它只比较前16个字节。类似地,任何其他接受GUID*
的WinAPI函数只检查前16个字节。
请注意,您不能为windows.h
假定通用的C或c++规则。例如,一个字节在Windows上总是8位,尽管ISO C允许9位。
每当你编写依赖于别人结构体大小的代码时,警铃应该响起。
你能给一些你想使用的简化代码的例子吗?如果需要结构体的大小,大多数人只会使用sizeof(GUID)。
话虽如此——我看不出GUID的大小有什么变化
#include <stdio.h>
#include <rpc.h>
int main () {
GUID myGUID;
printf("size of GUID is %dn", sizeof(myGUID));
return 0;
}
16。这有助于了解是否需要在堆上手动分配。