9

When I use the __FUNCTION__ macro/variable to print out debugging information, there seems to be a difference in what it outputs when using the Microsoft C++ compiler and gcc. For example, using the following trivial code:

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;
}

Using the Microsoft Visual C++ compiler, I get

__FUNCTION__ = Foo::Bar

whereas when compiling using gcc (in this case on the Mac), I get

__FUNCTION__ = Bar

The second example is not ideal because I quite often have several classes with, say, Init() and Uninit() methods and in a debug output trace its virtually impossible to tell which one of these has been called as the class name will be missing. Now, I know you can use the __PRETTY_FUNCTION__ in place of __FUNCTION__ to get something like

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

Which is fine, but its a bit too verbose for what I need and gets a bit long for functions with a lot of parameters.

So my question is (at last), is there any way to get the output to look like simply Foo::Bar using gcc, as in the example above?

binarybob
  • 3,529
  • 3
  • 23
  • 21
  • I'm curious as I have never needed this macro, why do you need it? Does your compiler/test suite/memory checker not tell you the exact line of code where the problem occurs? - if its for logging then I suggest writing logs that will be identical no matter the compiler used - for then you can write pattern matching tools to analyse the logs. – Tom Oct 04 '11 at 15:07
  • possible duplicate of [What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?](http://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func) – Sebastian Mach Oct 04 '11 at 15:19
  • Not a duplicate -- that question has nothing to say about how to get a Microsoft-style string out of GCC. – Steve Jessop Oct 04 '11 at 15:27
  • @Steve and porkchop: I am sorry, I was too fast, though the title is not unmisleading then. – Sebastian Mach Oct 04 '11 at 15:30
  • 2
    @phresnel: I've edited the title, based on the question in the last line of the body. porkchop: hope the new title represents what you actually wanted to know :-) – Steve Jessop Oct 04 '11 at 15:33
  • 1
    Btw, in case it matters `__FUNCTION__` isn't really a macro. Microsoft documents it along with its implementation-specific macros, but the clue is that it's not actually substituted by the preprocessor when you compile with `/P`. The C99 and C++11 standards don't define `__func__` as a macro (and it doesn't yield a string literal), and gcc comes right out and documents that they aren't. The reason is just that the preprocessor is too dumb to recognise a function definition. – Steve Jessop Oct 04 '11 at 15:35
  • @Steve: Thanks for that, I did struggle to find a title which conveyed what I wanted to say in the rest of the question and wasn't massively long. Yours covers it nicely! – binarybob Oct 04 '11 at 15:39

2 Answers2

3

If you are using it for tracing, you can always use typeid(T).name() and just conditionally compile per platform. Certainly not as convenient as the macro, but it could work.

Vaguely similar to __CLASS__ macro in C++

Community
  • 1
  • 1
Tom Kerr
  • 10,444
  • 2
  • 30
  • 46
  • Going this route with GCC the [demangling library](http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html) might come in handy. – user786653 Oct 04 '11 at 15:55
2

The function-name sanctioned by the standard is defined as follows:

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

Example:

#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();
}

However, output with g++:

main
foobar
foobar
barfoo

However, that is valid C++ behaviour:

§ 8.4.1, 8: The function-local predefined variable __func__ is defined as if a definition of the form static const char __func__[] = "function-name "; had been provided, where function-name is an implementation-defined string. It is unspecified whether such a variable has an address distinct from that of any other object in the program

I.e., you may not trust in its value. If you want to use non-portable extensions, have a look at a similar question: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? .

Community
  • 1
  • 1
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130