【问题标题】:How do I imitate the Microsoft version of __FUNCTION__ using gcc?如何使用 gcc 模仿 Microsoft 版本的 __FUNCTION__?
【发布时间】:2011-11-30 18:52:02
【问题描述】:

当我使用__FUNCTION__ 宏/变量打印出调试信息时,使用 Microsoft C++ 编译器和 gcc 时输出的内容似乎有所不同。例如,使用以下简单代码:

class Foo 
{
    public:
       void Bar(int a, int b, int c)
       {
           printf ("__FUNCTION__ = %s\n", __FUNCTION__);
       }
};

int main (void)
{
    Foo MyFoo;

    MyFoo.Bar();

    return 0;
}

使用 Microsoft Visual C++ 编译器,我得到了

__FUNCTION__ = Foo::Bar

而当使用 gcc 编译时(在这种情况下是在 Mac 上),我得到了

__FUNCTION__ = Bar

第二个例子并不理想,因为我经常有几个类,比如 Init()Uninit() 方法,并且在调试输出跟踪中几乎不可能知道其中哪一个被称为类名将丢失。现在,我知道您可以使用__PRETTY_FUNCTION__ 代替__FUNCTION__ 来获得类似的东西

__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int)

这很好,但是对于我需要的东西来说它有点过于冗长,并且对于具有很多参数的函数来说有点长。

所以我的问题是(最后),有没有什么方法可以让输出看起来像简单的Foo::Bar 使用 gcc,就像上面的例子一样?

【问题讨论】:

  • 我很好奇,因为我从来不需要这个宏,你为什么需要它?您的编译器/测试套件/内存检查器是否没有告诉您发生问题的确切代码行? - 如果它用于日志记录,那么我建议编写无论使用何种编译器都相同的日志 - 因为那么您可以编写模式匹配工具来分析日志。
  • 不是重复的——这个问题与如何从 GCC 中获取 Microsoft 风格的字符串无关。
  • @phresnel:我已经根据正文最后一行的问题编辑了标题。猪排:希望新标题代表你真正想知道的:-)
  • 顺便说一句,以防万一__FUNCTION__ 并不是真正的宏。 Microsoft 将其与特定于实现的宏一起记录在案,但线索是当您使用/P 编译时,它实际上并没有被预处理器替换。 C99 和 C++11 标准没有将 __func__ 定义为宏(并且它不会产生字符串文字),并且 gcc 会立即出现并记录它们不是。原因只是预处理器太笨,无法识别函数定义。

标签: c++ windows macos gcc compiler-construction


【解决方案1】:

如果您使用它进行跟踪,您始终可以使用typeid(T).name() 并按平台有条件地编译。当然不如宏方便,但它可以工作。

有点类似于__CLASS__ macro in C++

【讨论】:

【解决方案2】:

标准认可的函数名定义如下:

static const char __func__[] = "function-name ";

例子:

#include <iostream>

namespace meh {
    void foobar() { std::cout << __func__ << std::endl; }
};

struct Frob {
    void foobar() { std::cout << __func__ << std::endl; }
    static void barfoo() { std::cout << __func__ << std::endl; }
};

int main () {
    std::cout << __func__ << std::endl;
    meh::foobar();
    Frob().foobar();
    Frob::barfoo();
}

但是,使用 g++ 输出:

main
foobar
foobar
barfoo

但是,这是有效的 C++ 行为:

§ 8.4.1, 8:函数局部预定义变量__func__ 被定义为static const char __func__[] = "function-name "; 形式的定义 已提供,其中 function-name 是实现定义的字符串。未指定此类变量的地址是否与程序中任何其他对象的地址不同

也就是说,您可能不相信它的价值。如果您想使用非便携式扩展,请查看类似问题:What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 2011-06-14
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多