为什么偏移实现在C和C++上奇怪地不同?

Art*_*nov 4 c c++ offsetof

我打开stddef.h并看到了这个:

#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
Run Code Online (Sandbox Code Playgroud)

__cplusplus(在C++编译器的情况下)的分支中有非常奇怪的实现,我认为它是多余的.其他分支(C编译器的情况)具有更简单的字段偏移计算.我测试了它,它的工作原理.对于在第一种情况下使用这种奇怪的强制转换和类型限定符的内容?

Rei*_*ica 10

operator &可以为类型重载m,所以&((s*)0)->m)会调用它operator &而不是取m地址.

并且const volatile有在reinterpret_cast的类型,以便它的作品,即使mconst和/或volatile.

请注意,在C++ 11中,无论过载如何std::addressof(x),都始终采用地址.它可能以与您在问题中看到的方式类似的方式实施.xoperator &

  • 请注意,C++ 11及更高版本具有[`std :: addressof()`](http://en.cppreference.com/w/cpp/memory/addressof)来处理`operator&`问题.`offsetof()`可以写成`#define offsetof(s,m)((size_t)std :: addressof(((s*)0) - > m))` (4认同)