0

There are some special macros supported by most compilers, such as __FUNC__ or __PRETTY_FUNCTION__ but I am wondering how can I verify if these are available during compile time, there is this Boost macro from boost/current_function.hpp:

#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600))

# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__

#elif defined(__DMC__) && (__DMC__ >= 0x810)

# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__

#elif defined(__FUNCSIG__)

# define BOOST_CURRENT_FUNCTION __FUNCSIG__

#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))

# define BOOST_CURRENT_FUNCTION __FUNCTION__

#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)

# define BOOST_CURRENT_FUNCTION __FUNC__

#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)

# define BOOST_CURRENT_FUNCTION __func__

#else

# define BOOST_CURRENT_FUNCTION "(unknown)"

#endif

However, does it really need to be so complex? Isn't it possible to #ifdef __PRETTY_FUNCTION__ instead so that it would use this macro even on compilers that are not known by boost or the person who wrote the macro? For example:

#if defined(__PRETTY_FUNCTION__)

# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__

#elif defined(__FUNCSIG__)

# define BOOST_CURRENT_FUNCTION __FUNCSIG__

#elif (defined(__FUNCTION__)

# define BOOST_CURRENT_FUNCTION __FUNCTION__

#elif defined(__FUNC__)

# define BOOST_CURRENT_FUNCTION __FUNC__

#elif defined(__func__)

# define BOOST_CURRENT_FUNCTION __func__

#else

# define BOOST_CURRENT_FUNCTION "(unknown)"

#endif

What is a difference? Would it work on all compilers?

Petr
  • 13,747
  • 20
  • 89
  • 144
  • It is "complex" because it isn't standardized. Hard to guess why you need to find this out at runtime. It is trivial at compile time, you get a compile error. So you'll never make it to runtime :) It can only work at compile time, unless you do something untrivial with debug info. Which is a *lot* more platform dependent and a wholeheckoflot more complex than using the macro. – Hans Passant Nov 27 '14 at 16:36
  • Sorry I didn't mean runtime :) fixed it – Petr Nov 27 '14 at 22:21

1 Answers1

2

See https://stackoverflow.com/a/4384825/583195.

It quotes:

The identifier __func__ is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

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

appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function.

This indicates that __func__ and many of the other "magic macros" are not macros at all, and therefore not picked up by #ifdef

Community
  • 1
  • 1
Allison Lock
  • 2,375
  • 15
  • 17
  • The standard says "The function-local predefined variable `__func__` is defined as if a definition of the form `static const char __func__[] = "function-name ";` had been provided..." This means that it is not required for `__func__` to be #defined (although it could be in some compilers). Other "magic macros" are not part of the standard, so any compiler that does implement them can implement them however it sees fit (as #defines, local vars, etc.). Because of this inconsistency, Boost have resorted to compiler-sniffing. – Allison Lock Nov 28 '14 at 08:30