这两个offsetof宏有什么区别?

时间:2016-01-29 09:11:09

标签: c++ macros

我看到了这两个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))

2 个答案:

答案 0 :(得分:0)

reinterpret_cast<type>(expression)expression,它告诉编译器将表达式(((s*)0)->m)中给出的一系列位作为类型<char const volatile&>而不是原始类型。它们仍然在相同的数据上运行,只有编译器将数据视为顶部表达式中的不同数据类型。

答案 1 :(得分:0)

operator&可以在C ++中重载。如果operator&(const M&)存在用户定义的重载,其中Mdecltype((s*)0)->m)(即成员的类型),如果重载没有返回对象的地址,那么宏如果没有重新解释,则表现不正常。

char引用可能是专门使用的,因为charunsigned char允许special guarantees允许对任何类型进行别名,并且因为运算符不能为基本类型重载。 const volatile限定符可能是这样的,如果成员碰巧拥有它们,编译器就不会发出关于丢弃这些限定符的警告。

正如T.C在评论中指出的那样,额外的演员可能是为了防止用户定义的重载。 C没有超载,因此不需要保护性铸件。