【发布时间】:2010-10-11 07:12:15
【问题描述】:
我正在编写 C 跨平台库,但最终我的单元测试出现错误,但仅限于 Windows 机器上。我已经跟踪了这个问题,发现它与结构的对齐有关(我正在使用结构数组来保存多个相似对象的数据)。问题是:memset(sizeof(struct)) 和一个一个地设置结构成员会产生不同的字节到字节的结果,因此 memcmp() 返回“不相等”的结果。
这里是说明的代码:
#include <stdio.h>
#include <string.h>
typedef struct {
long long a;
int b;
} S1;
typedef struct {
long a;
int b;
} S2;
S1 s1, s2;
int main()
{
printf("%d %d\n", sizeof(S1), sizeof(S2));
memset(&s1, 0xFF, sizeof(S1));
memset(&s2, 0x00, sizeof(S1));
s1.a = 0LL; s1.b = 0;
if (0 == memcmp(&s1, &s2, sizeof(S1)))
printf("Equal\n");
else
printf("Not equal\n");
return 0;
}
此代码与 MSVC 2003 @ Windows 产生以下输出:
16 8
Not equal
但与 GCC 3.3.6 @ Linux 相同的代码可以按预期工作:
12 8
Equal
这让我的单元测试非常困难。
我是否正确理解 MSVC 使用最大原生类型(long long)的大小来确定与结构的对齐方式?
谁能给我建议,我该如何更改我的代码以使其更健壮地解决这个奇怪的对齐问题?在我的真实代码中,我通过通用指针使用结构数组来执行 memset/memcmp,而且我通常不知道确切的类型,我只有 sizeof(struct) 值。
【问题讨论】:
-
我想指出,在您的代码中,
s1和s2都被声明为S1类型。这两个变量都不是真正的S2。不过,这可能只是一个错字。 -
这不是错字。 S2 结构没有
long long成员,因此不会给我造成问题。 -
使用
memcmp比较结构无效,句号。使用#pragmahacks 和关于对齐的错误假设来试图使其工作是错误的。
标签: c unit-testing cross-platform struct alignment