Как имитировать версию Microsoft __FUNCTION__ с помощью gcc? - PullRequest
8 голосов
/ 04 октября 2011

Когда я использую макрос / переменную __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, как в примере выше?

Ответы [ 2 ]

3 голосов
/ 04 октября 2011

Если вы используете его для трассировки, вы всегда можете использовать typeid(T).name() и просто условно компилировать для каждой платформы.Конечно, не так удобно, как макрос, но он может работать.

Смутно похоже на макрос __ CLASS__ в C ++

2 голосов
/ 04 октября 2011

Имя функции, разрешенное стандартом, определяется следующим образом:

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 "; где функция-name является строкой, определенной реализацией. Не указано, имеет ли такая переменная адрес, отличный от адреса любого другого объекта в программе

Т.е., вы не можете доверять его ценности. Если вы хотите использовать непереносимые расширения, взгляните на похожий вопрос: В чем разница между __PRETTY_FUNCTION__, __FUNCTION__, __func __? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...