据我所知,"offsetof"宏定义为:
#define offsetof(st, m) ((size_t)(&((st *)0)->m))
基于此链接:http://en.wikipedia.org/wiki/Offsetof
所以我编写了自己的代码片段来计算结构成员的偏移量:
typedef struct{
char a;
int b;
int c;
}example_struct;
int main(int argc, char *argv[])
{
example_struct *p = 0;
printf("%pn", &(p->a)); --> 00000000
printf("%pn", &(p->b)); --> 00000004
printf("%pn", &(p->c)); --> 00000008
printf("%pn", &(p->a)); --> 0
printf("%pn", &(p->b)); --> 4
printf("%pn", &(p->c)); --> 8
cout << &(p->a); --> this line cause crash ???
cout << &(p->b); --> 00000004
cout << &(p->c); --> 00000008
cout << (unsigned int)&(p->a); --> 0
cout << (unsigned int)&(p->b); --> 4
cout << (unsigned int)&(p->c); --> 8
return 0;
}
我的问题是:
- 类型转换是否会导致崩溃。为什么不能计算第一个成员的偏移量,而printf可以
- 我们为什么要键入cast。必须这样做吗
任何意见都将受到真诚的赞赏:)
据我所知,"offsetof"宏被定义为。。。
事实并非如此,它被定义为。它可以这样定义。通常,在NULL
指针上执行指针运算会导致未定义的行为,但如果您的C库碰巧这样做,那么它在您的特定系统上一定没问题。
顺便说一句,这对我来说也会在带有clang++
的OS X 10.9上崩溃。不过,使用offsetof
时,它不会崩溃。结论:未定义的行为是未定义的,实现细节是实现细节,不应该依赖它们或对它们做出假设。