【问题标题】:How can I obtain the identifier of the current function?如何获取当前函数的标识符?
【发布时间】:2014-03-11 08:45:42
【问题描述】:

在 C/C++ 中,我们有 __FUNCTION__ 宏,它被替换为字符串,包含当前函数的名称。但是如果我想要函数的标识符怎么办?也就是说,不是字符串,而是我可以用作标记来创建其他标识符的东西,例如,如果我们有

#define MAGIC /* ... */

#define MORE_MAGIC MAGIC ## _bar

void foo() {
    printf("%s\n",__FUNCTION__);
    MORE_MAGIC();
}

void foo_bar() {
    printf("%s\n",__FUNCTION__);
}

void baz() {
    printf("%s\n",__FUNCTION__);
    MORE_MAGIC();
}

void baz_bar() {
    printf("%s\n",__FUNCTION__);
}

int main() {
    foo();
}

应该打印

foo
foo_bar
baz
baz_bar

注意事项:

  • 我只对预处理时间感兴趣。
  • 我宁愿不使用预处理器调用替换我的函数定义 - 尽管我知道这可能会起作用。

【问题讨论】:

  • C 和 C++ 没有introspection,所以不可能。您可以在函数名和函数指针之间进行手工映射,但无法实现自动化。
  • @JoachimPileborg:我相信 OP 询问的是编译时魔法,而不是运行时魔法(即内省)。
  • @JoachimPileborg 我同意自动化通常会很困难,如果不是不可能的话,但是对于特殊情况来说可能很容易,这取决于@einpoklum 对讨厌的宏的容忍度。您可以定义扩展为函数原型的 DEF_FUNC 宏以及在某种函数指针表中注册函数。 IE。 DEF_FUNC(f) void f() { REGISTER(f, __FUNCTION__)
  • 通常 c/c++ 预处理器不进行字符串操作,但如果你有比@JoachimPileborg 答案更复杂的情况,下面的 easilty 支持并愿意冒险研究奇怪的东西,就会有这样的事情: insanecoding.blogspot.se/2011/10/stronger-cc-preprocesser.html
  • 不得不问:你认为你为什么需要这个?

标签: c++ c macros c-preprocessor


【解决方案1】:

很遗憾,你不能。因为你不能unstringify宏[1]。

换句话说,您不能删除__FUNCTION__生成的字符串周围的引号并通过_bar联系它。

【讨论】:

  • 我同意。在类似的情况下,我必须编写一个 C++ 包装器,我只是编写了一个 perl 脚本,它在编译时将 foo.cpp.tmpl 处理成最终的 foo.cpp
  • 是的,__FUNCTION__ 是一个字符串文字,你无能为力。
  • 我没有说我想取消字符串化 FUNCTION,我想知道编译器或预处理器是否直接提供我感兴趣的功能。
  • @einpoklum:我明白你的意思。标准 C++ 中的一种可能性是取消字符串化 __FUNCTION__,这是不可能的。也许有一种编译器魔法可以做到这一点,但这不是一种标准和可移植的方式。
【解决方案2】:

如果它是您想要的编译时间,并且对于像您这样的简单情况,预处理器宏和连接运算符## 可能是可能的。也许像

#define MORE_MAGIC(f) f##_bar

...

void foo_bar()
{
}

void foo()
{
    MORE_MAGIC(foo)();
}

虽然不能自动获取名称foo,但必须在宏“call”中明确命名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2020-02-28
    • 2012-05-10
    • 1970-01-01
    • 2020-06-04
    • 2011-04-30
    相关资源
    最近更新 更多