【发布时间】:2020-02-03 15:11:25
【问题描述】:
我写了一小段代码来了解 offsetof 宏在后台是如何工作的。代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = (unsigned)(&((MyStructType * )NULL)->c);
printf("offset = %u\n", offset);
return 0;
}
但是,如果我运行它,我会收到一条警告消息:
警告:从指针转换为不同大小的整数 [-Wpointer-to-int-cast]
但是,如果我查看 c 中的原始 offsetof 宏,代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = offsetof(MyStructType, c);
printf("offset = %u\n", offset);
return 0;
}
那么为什么我在转换为 unsigned 时会收到警告?它似乎是 offsetof 宏的类型。这让我很困惑。
【问题讨论】:
-
of different size表示指针的值可能不适合unsigned。你应该投到uintptr_t。 -
我猜?您在 64 位系统上,其中指针为 64 位宽,
unsigned(又名unsigned int)为 32 位宽。请改用uintmax_t或uintptr_t或size_t。 -
请注意,
&((MyStructType * )NULL)->c取消引用NULL指针并且是未定义的行为。 -
您可能需要转换为
uintptr_t,然后转换为size_t(因为offsetof应该产生size_t)。 -
@Meerkat 只有当
uintptr_t值不适合size_t时才会出错。但是由于size_t可以保存任何对象的大小,它也可以保存结构对象的任何成员的偏移量。