我正在包装一个脚本库,这个宏存在。
#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)
m
是什么类型的?它有一个例子:
struct MyStruct
{
int a;
};
asOFFSET(MyStruct,a)
我想把它放到一个函数中。
答案 0 :(得分:1)
这是offsetof
宏的实现。 m
是s
的任何成员。它没有相应的C或C ++类型 - 但与pointer to member的概念密切相关。
答案 1 :(得分:1)
脚本库(很可能)使用宏来查找类成员的内部布局,而不对其类型,体系结构或继承模型做出假设。 (一个简单的例子是discussed here)。
对于大多数C ++程序,理想情况下根本不需要这些信息(内存布局)。但是,如果您确实需要它(例如,如果您正在编写分析器/调试器),最好保留此宏(或者最好用代码{{1}替换它在代码中的用法正如迈克尔安德森指出的那样。)compiler-specific implementations是
使用这些等效选项,理想情况下不需要手动旋转替代或包装。
答案 2 :(得分:0)
宏的目的是确定,给定结构的任何名称和该结构成员的任何名称,内存中的距离< / em>从结构的任意实例的开头,以及该成员在同一实例中的位置。
m
没有“类型”,s
也没有。当你使用宏时,“type”的整个概念就会出现在窗口中。这个东西只是不是C ++ ;它基本上是一种完全独立的语言,用于就地编辑C ++代码。当预处理器运行时,asOFFSET(MyStruct, a)
将在编译器开始工作之前替换为文本 ((size_t)(&reinterpret_cast<MyStruct*>(100000)->a)-100000)
。
((size_t)(&reinterpret_cast<MyStruct*>(100000)->a)-100000)
旨在评估为0,因为a
个实例的MyStruct
成员出现在每个实例的开头。我实际上并不是100%确定这是符合规范的合法行为,但意图如下:
通过将数字MyStruct
视为指向100000
的指针,假设内存位置100000
上存在MyStruct
的实例
获取此假结构的a
成员的内存地址,然后再次减去100000
。这给了我们从伪结构的开头到伪结构的指定成员的距离。
将该数值转换回size_t
(用于测量内存分配的数字类型,无符号整数类型)。