我可以通过函数传递这个吗?

时间:2014-06-16 06:25:55

标签: c++ templates types

我正在包装一个脚本库,这个宏存在。

#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)

m是什么类型的?它有一个例子:

struct MyStruct
{
  int a;
};

asOFFSET(MyStruct,a)

我想把它放到一个函数中。

3 个答案:

答案 0 :(得分:1)

这是offsetof宏的实现。 ms的任何成员。它没有相应的C或C ++类型 - 但与pointer to member的概念密切相关。

答案 1 :(得分:1)

脚本库(很可能)使用宏来查找类成员的内部布局,而不对其类型,体系结构或继承模型做出假设。 (一个简单的例子是discussed here)。

对于大多数C ++程序,理想情况下根本不需要这些信息(内存布局)。但是,如果您确实需要它(例如,如果您正在编写分析器/调试器),最好保留此宏(或者最好用代码{{1}替换它在代码中的用法正如迈克尔安德森指出的那样。)compiler-specific implementations

  1. 更有效率
  2. 不太可能被报告为执行无效操作(例如,在使用Valgrind等工具时解除引用无效的内存地址)。
  3. 使用这些等效选项,理想情况下不需要手动旋转替代或包装。

答案 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(用于测量内存分配的数字类型,无符号整数类型)。