【问题标题】:c++: address to string constantc ++:字符串常量的地址
【发布时间】:2010-11-03 12:11:57
【问题描述】:

我可以在 g++ 中将对象的地址作为字符串常量获取吗?示例:

struct s { } x;

如果&x == 1234,那么我的代码中需要"1234"

编辑

字符串常量是指我在编译或链接时需要该常量字符串。我需要将它嵌入到这样的内联汇编代码中:

template < typename U >
struct T {
  static int x;
  void f () {
    asm (".word " some-expression-containing-(&x));
  }
};

我不知道如何使用预处理器宏构造损坏的名称,所以我问了这个问题。

方案不需要便携,g++就够了。

地址本身在编译或链接时是已知的,因为它可以检查汇编输出并将损坏的名称放入内联汇编指令中。

【问题讨论】:

  • x 的地址在编译时(不一定)知道。
  • 只需编写一个包含名称的目标文件,然后使用nm 查看生成的目标文件的导出表。这将显示对象的错位名称。
  • @Konrad:我的问题是该对象是一个模板类,我需要为不同的模板参数生成不同地址的代码的多个实例化。必须在目标文件中查找每个可以想象的错位名称并不是一件好事。
  • 你不能通过在模板化方法中使用内联程序集来做到这一点吗?
  • FWIW,询问如何获取字符串常量而不是如何获取用于 asm 的变量地址是 XY problem 的示例。

标签: c++ string constants memory-address


【解决方案1】:

我想知道你为什么需要那个......但你可以这样做:

#include <sstream>
#include <cstddef> //for ptrdiff_t
....
stringstream ss;
ss << reinterpret_cast<ptrdiff_t>(&x);

ss.str() 现在包含您想要的字符串

编辑:如果您想在编译时执行此操作...呃...我敢假设 这是不可能的 em>

【讨论】:

  • int 不是很便携,ptrdiff_t 可能是更好的选择
  • 我需要编译时的地址。需要写一些东西作为`asm(“.word” some-expression-that-c​​ontains-an-address),并且对象的名称将有一个难以修改的名称,所以我看不到用它构造它的方法一个宏。
  • 你不需要投射; operator &lt;&lt; 为指针重载。
  • @Oli:重载以十六进制打印,不是吗?
  • @Thomas:不,它在链接时已知,但在编译时不知道。
【解决方案2】:
template<class U>
struct T {
  static int x;
  void f () {
    asm (".word %0" : "m" (&x));
  }
};

这个works 给我g++

【讨论】:

  • 这可能是解决方案,但在我的情况下它无法编译:asm ("brsl $lr, %0" : "m" (&amp;buf&lt;prg&gt;::obj.store));(其中brsl 是powerpc 上的“调用”指令)导致error: lvalue required in asm statementerror: output operand constraint lacks '='。也许我错过了一些简单的东西......
  • @Thomas:看起来你需要modify 约束。不幸的是,我在编写 asm 方面非常糟糕,而且阅读它的能力也很一般(只有当我手头有很多文档时才会这样)。
  • @Roger:嗯...我也没有组装经验,我现在正在尝试一些修饰符和约束的组合。我想知道为什么 g++ 将 %0 识别为“输出”操作数,它应该是一个输入。使用 intel 而不是 AT&T 语法时可能需要更改某些内容(如果此差异与 powerpc 有关)?
  • asm ("brsl $lr, %0" :: "rm" (&amp;buf&lt;prg&gt;::obj.store)); 编译,但给出了一些奇怪的警告
  • @thomas:也许您应该尝试将约束更改为 p 而不是 rm
【解决方案3】:

你可以的

asm(".word x")

(它仅适用于文件范围变量符号,因为只有它们可能获得符号表条目)。它不是常量表达式,但地址在程序完全链接之前是未知的。

【讨论】:

  • 是的,这就是我想要实现的目标——但是由于 x 的名称很复杂(我不知道,因为 x 的类是模板化的,可能有几个 x 用于不同的模板参数),我认为直接提供地址作为字符串常量可能更容易。
【解决方案4】:

在 C 中,您可以这样做,但在 C 中,由于您使用 char *'s 作为字符串,您需要这样的东西:

printf("%i-%i", &string[0], &string[strlen(string) - 1]);

打印字符串所在的内存范围,而不是起始地址。

【讨论】:

    【解决方案5】:

    错误输出操作数约束缺少=是因为在操作符outm之前没有操作符=。以=m

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-19
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多