【发布时间】:2016-01-18 06:43:15
【问题描述】:
规格:
编译器:TDM-GCC 5.1.0
操作系统:Windows 8.1 64 位
我对 C++ 标准库进行了非常彻底的搜索,进行了一些其他研究,甚至在一些内联汇编方面达到了顶峰。但我还没有得出结论,所以这里是:
考虑到我的编译器,如果我知道原始类型的地址和大小,C++(最高 C++14)有什么方法可以从这些信息中推断出类型,以及查看原始数据在内存中(我也愿意使用内联汇编)?
一个例子:
如果我声明了以下内容:
float x = 1.0f;
int y = 0x3f800000; //The same raw value in memory as 'x'
有没有什么办法,只看这些变量的原始内容,就可以推断出它们的类型?
如果简单的答案是“不”,那么请让我给你这个问题的背景,也许你可以指出我正确的方向。
简而言之,我正在尝试编写一个可以在运行时剖析/分析类的函数(在尽可能远的范围内,因为 C++ 唯一真正的元编程是模板)。我希望能够在给定该类的实例的情况下确定该类的成员对象。 “type_traits”库在这里并没有真正帮助我,并且 'sizeof()' 和 'alignof()' 提供了提示,但它没有足够的信息来推断成员对象。而且 'typeid()' 没用,因为我使用的是 void 指针,除了获取类的名称。
C++ ABI/RTTI 有一些不错的元编程。
【问题讨论】:
-
运行时这些信息都不存在。
-
如果您想要类似的东西(运行时反射),您仍然可以定义自己的类型(类),而不是使用本机类型。
class Reflectable { uint32_t typeId; Reflectable(uint32_t tId) : typeId(tId) {}; uint32_t getType() const { return typeId; } }; class MyFloat : public Reflectable { MyFloat( float value } : Reflectable(42), value(v) {}; }; -
不同的编译器对自省有不同的(非标准)支持。我的印象是clang给你的最多,g++一些,至少有2个g++自省库,msvc最少。
-
编译器可以生成的“调试信息”可以为您提供该信息。您可以在不关闭优化的情况下打开它。即使没有这些调试符号,编译器也可以为您提供有关类型二进制布局的信息。但是,您必须从已知类型开始,从原始内存中推断出该类型将是猜测(并非不可能,但很困难且容易出错)。
-
@PaulRich:运行时不提供该信息。对于 C++03,这对于自动垃圾收集器(例如 Boehm 收集器)来说是一个真正的问题(我从未使用过它)。但是,您也可以通过考虑对齐来更好地猜测。
标签: c++ pointers memory metaprogramming type-deduction