就在这个问题因重复而被驳回之前,大多数(如果不是全部)问题都已接受答案,并带有过时/未定义的行为解决方案。
有没有办法在编译时获得指向成员数据的指针的偏移量:
nullptr事物)gcc trunk在编译器资源管理器中)offsetof(或类似地,就像提议的代码一样)。使用 GCC 的主干版本,以下技巧(hack)不起作用:
#include <cstdint>
#include <cstddef>
namespace detail
{
// The union stuff is for CLang to avoid creating warnings
template<typename T, auto MPtr>
struct offsetof_ptr_helper
{
union helper_t { int i = 0; T value; };
static constexpr helper_t v = {};
static constexpr size_t sz = sizeof
(uint8_t[
(uint8_t *)&(v.value.*MPtr) -
(uint8_t *)&v.value
]);
};
}
template<typename T, auto MPtr>
static constexpr size_t offsetof_ptr()
{
return detail::offsetofptr_helper<T, MPtr>::sz;
}
size_t f()
{
struct X { char c[10]; int a; };
return offsetof_ptr<X, &X::a>();
}
Run Code Online (Sandbox Code Playgroud)
需要明确的是,这是一个使用 C++98 特性的 hack,它的支持被最新的编译器删除并不令人意外。它适用于 clang(使用-std=gnu++17标志)和 gcc(包括/高达 g++ 7.3 使用标志-std=c++17)。
如果你跳到 VS 中的定义offsetof,它会给你这个:
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
Run Code Online (Sandbox Code Playgroud)
稍微修改一下以匹配您的问题:
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
Run Code Online (Sandbox Code Playgroud)
它可以在 GCC 和 MSVC 上编译。(由于模板自动参数,它需要 C++17。)