I'm wondering how widely are __func__
(part of C99, but I'm compiling as C89) and __FUNCTION__
supported.
I have an old code base that is mostly using manual const char* id;
variables that are then passed to various (mostly logging) functions. I would like to get rid of this and move the function name into a macro.
The predefined identifier __func__
was added to the 1999 ISO C standard; the older 1990 C standard doesn't have it.
Support for __func__
in pre-C99 compilers will depend on which compiler you're using.
Modern versions of gcc support __func__
even in C90 mode (-ansi
or -std=c89
).
Before __func__
was added to the standard, gcc implemented its own equivalent extension, but with the name __FUNCTION__
. (gcc also supports __PRETTY_FUNCTION__
, which is identical to __func__
and __FUNCTION__
for C, but provides more information in C++.)
The gcc manual gives some advice:
__FUNCTION__
is another name for__func__
. Older versions of GCC recognize only this name. However, it is not standardized. For maximum portability, we recommend you use__func__
, but provide a fallback definition with the preprocessor:
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
which implies that gcc added support for __FUNCTION__
in version 2. gcc 2.0 was released in 1992; you're very unlikely to be using a version of gcc that doesn't support at least __FUNCTION__
, if not __func__
.
Note that since __func__
and __FUNCTION__
are predefined identifiers, not macros, you only need the #define
once, not in each function. On the other hand, you can't use #ifdef __func__
or #ifdef __FUNCTION__
to detect the level of support.
As for other compilers, a quick experiment indicates that Microsoft Visual C++ 2010 Express supports __FUNCTION__
, but not __func__
or __PRETTY_FUNCTION__
, when compiling C code. The above block of code from the gcc manual compiles under MSVC, but it results in __func__
being defined as "<unknown>"
. It shouldn't be too difficult to adjust it to recognize that MSVC supports __FUNCTION__
. (I don't know whether older versions do so.) You can probably use the predefined macro _MSC_VER
for this. Microsoft's documentation says that support for __FUNCTION__
goes back at least to the 2003 release, which sets _MSC_VER
to 1300
, so changing the second line to
# if __GNUC >= 2 || _MSC_VER >= 1300
is a good start. (It may well have been supported in earlier releases.)
For compilers other than gcc and MSVC, you'll have to consult their respective documentation -- but in any case, the block of code recommended in the gcc manual should work for any compiler, at worst falling back to "<unknown>"
.
The boost current_function.hpp header contains several #define
s for the ways to get the current function on different platforms.
That's not to say that those platforms don't support other ways of getting the current function, but the choices made for boost are likely to represent nice (if not the nicest) ways of getting the information on those platforms.
An adaptation of this header for your code (and for C) could well be what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With