C++ 通过强制转换null ptr获取成员变量的偏移量
我正在查看C++ 通过强制转换null ptr获取成员变量的偏移量,c++,offsetof,C++,Offsetof,我正在查看中的宏,并看到可能的实现是通过 #define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member)) 我试过了,果然果然如期而动 #include <iostream> #define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member)) struct S { char x; s
中的宏,并看到可能的实现是通过
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
我试过了,果然果然如期而动
#include <iostream>
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
struct S
{
char x;
short y;
int z;
};
int main()
{
std::cout << my_offsetof(S, x) << '\n';
std::cout << my_offsetof(S, y) << '\n';
std::cout << my_offsetof(S, z) << '\n';
S s;
std::cout << (void*) &((&s)->x) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->y) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->z) << '\n'; // no more relative offsets
}
#包括
#定义(类型,成员)((void*)和((type*)nullptr)->member)的我的偏移量
结构
{
字符x;
短y;
intz;
};
int main()
{
std::cout member)
计算成员相对于0的地址,是否确实如此?(似乎如此,在最后3行中,我得到了相对于s
地址的偏移量)
(void*)
的最终强制转换,我会得到一个segfault。为什么?&((type*)nullptr)->成员)
不应该是type*
类型的指针,或者该类型在这里被删除了吗offsetof
,但这是因为它就是实现:它可以选择如何实现自己的功能。另一方面,你不会得到这样的“奢侈”
您无法以任何符合标准的方式实现宏的偏移量
这可能是因为试图打印
my_offset of(s,x)
(因为x
是char
,而该表达式会导致char*
),因为。取消对空指针的引用是错误的,即使它只是获取它的地址。@JonathanPotter这是我的想法,尽管我不确定。所以CPP引用“可能的实现”被打破了。你将如何实现这个宏?@ VSOFTCO:不是C++中指定的所有东西都可以由用户重新实现。某些东西,如<代码> Office < <代码>或<代码> STD::,不能以符合标准的方式实现。@cornstales我明白了。std::complex
有什么问题吗?它不只是一个有两个成员和一些成员函数的结构吗?@vsoftco:它保证没有任何填充,可以转换为浮点[2]
(或双[2]
)数组..不确定我是否理解“编译器可能会选择以这种方式实现offsetof,但那是因为它是实现。“你的意思是编译器内部有一个定义良好的行为,在这种情况下,根据定义?@vsoftco:我的意思是编译器需要提供一些
宏的偏移量。但是,如何做到这一点取决于编译器。如果他们选择这样做,他们可以创建&((type*)nullptr)->成员)
宏的偏移量定义得很好。但这并不意味着你自己的宏定义得很好。@Cornstales,在你的最后一句话中s/可能/:)谢谢,这也是我从你的回答中理解的。哦,我也看到了字符的情况……出于某些原因,我认为类型是s*
,但类型是是指向该成员的指针,因此每当该成员是char
时,由于调用char*
重载,该指针就会断开+1@vsoftco您所做的可能不会在所有编译器上都起作用。但它可能在GCC 5上起作用。如果它在GCC上起作用,但在MSVC上不起作用,那么MSVC将提供自己的宏,该宏与在MSVC上起作用的宏不同。如果您使用自己的版本,然后您将不知道如何为MSVC更改它,并且您的代码将无法在MSVC上工作。