【问题标题】:Deducing Primitive Type from Raw Memory and Class Analyzers从原始内存和类分析器推导出原始类型
【发布时间】: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


【解决方案1】:

简单的答案:
不,在运行时不提供此信息。但是,您可以通过 alignof()、sizeof() 进行有根据的猜测,并了解特定尺寸类型通常使用的值范围。

或者创建您自己的反射 API。

【讨论】:

  • alignofsizeof 都要求您在编译时知道类型。
  • @TommyA 不是在您使用模板时。我对类分析器函数的尝试是函数模板,所以在函数中我不知道类型。
  • 你可能不知道类型,但你的编译器在编译时确实知道类型,在使用函数模板时也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2018-06-26
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多