我看到了这两个offsetof的宏:
#if defined(_MSC_VER) && !defined(_CRT_USE_BUILTIN_OFFSETOF)
#ifdef __cplusplus
#define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
#else
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
#endif
#else
#define offsetof(s,m) __builtin_offsetof(s,m)
#endif
它之间的区别是什么:
((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
和:
((size_t)&(((s*)0)->m))
?
答案 0 :(得分:0)
reinterpret_cast<type>(expression)
是expression,它告诉编译器将表达式(((s*)0)->m)
中给出的一系列位作为类型<char const volatile&>
而不是原始类型。它们仍然在相同的数据上运行,只有编译器将数据视为顶部表达式中的不同数据类型。
答案 1 :(得分:0)
operator&
可以在C ++中重载。如果operator&(const M&)
存在用户定义的重载,其中M
是decltype((s*)0)->m)
(即成员的类型),如果重载没有返回对象的地址,那么宏如果没有重新解释,则表现不正常。
char
引用可能是专门使用的,因为char
和unsigned char
允许special guarantees允许对任何类型进行别名,并且因为运算符不能为基本类型重载。 const volatile
限定符可能是这样的,如果成员碰巧拥有它们,编译器就不会发出关于丢弃这些限定符的警告。
正如T.C在评论中指出的那样,额外的演员可能是为了防止用户定义的重载。 C没有超载,因此不需要保护性铸件。