How to test for the existence of __func__?

D

dave_140390

Hi,

Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?

I mean, something similar to the following (which tests for the
existence of macro __LINE__):

#ifdef __LINE__
(code that uses __LINE__)
#else
(code that doesn't use __LINE__)
#endif

This technique cannot be used for __func__, because __func__ is a
variable, not a macro.

In theory, you could use this:

#if __STDC__ && __STDC_VERSION__ >= 199901L
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

Unfortunately, some pre C99 compilers already support __func__, and
some supposedly C99 compilers do not yet support __func__.

So, are we condemned to write tests such as:

#if (some version of compiler 1) || (some version of compiler 2) || ...
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

:(

-- dave
 
I

Ian Collins

Hi,

Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?
How about something like:

int main(void)
{
const char* s = __func__;
return 0;
}
 
R

Richard Bos

Ian Collins said:
How about something like:

int main(void)
{
const char* s = __func__;
return 0;
}

That's not clean; it breaks. The point was to avoid the breakage by
cleanly detecting the existence of __func__ and then (with #if) using it
or using something else, depending on whether it does exist.

No, I don't know how to do that, either. I'm not sure you can.

Richard
 
D

dave_140390

I certainly know how to determine whether a specific compiler supports
__func__ or not.

My point is:

How do you write two versions of your code, one that uses __func__ when
compiling the code with a compiler that supports __func__, the other
that doesn't use __func__ when compiling the code with a compiler that
doesn't support __func__ ?

-- dave
 
H

Hallvard B Furuseth

dave_140390 said:
#if __STDC__ && __STDC_VERSION__ >= 199901L
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

Unfortunately, some pre C99 compilers already support __func__, and
some supposedly C99 compilers do not yet support __func__.

So, are we condemned to write tests such as:

#if (some version of compiler 1) || (some version of compiler 2) || ...
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

I'd use a mixture of the two: Start with the former, add special cases
when people complain if there really are compilers that #define
__STDC_VERSION__ >= 199901L but do not define __func__, and accept that
users of some compilers won't get __func__ even though their compiler
supports it. Then wait for the situation to improve over time.

Maybe it'll help to add '... || defined(__func__)' in case some compiler
has decided to be helpful and #define __func__ so you can test it.

Besides, that makes special cases for some compilers simpler, e.g. if
you wish to add:
#if __STDC_VERSION__ < 199901L && __GNUC__ >= 2
# define __func__ __FUNCTION__
#endif
 
R

Rod Pemberton

Hi,

Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?

I mean, something similar to the following (which tests for the
existence of macro __LINE__):

#ifdef __LINE__
(code that uses __LINE__)
#else
(code that doesn't use __LINE__)
#endif

This technique cannot be used for __func__, because __func__ is a
variable, not a macro.

What about for __FUNCTION__? Actually, the one compiler I tried didn't
recognize '#ifdef __FUNCTION__'.
In theory, you could use this:

#if __STDC__ && __STDC_VERSION__ >= 199901L
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

A slight variation which might be useful:
http://lists.gnupg.org/pipermail/gnupg-commits/2006-June/006505.html
Unfortunately, some pre C99 compilers already support __func__, and
some supposedly C99 compilers do not yet support __func__.

So, are we condemned to write tests such as:

#if (some version of compiler 1) || (some version of compiler 2) || ...
(code that uses __func__)
#else
(code that doesn't use __func__)
#endif

Probably, since you can't, or so it seems, directly test for __func__ or
__FUNCTION__ with the preprocessor.

Most compilers seem to support __FUNCTION__ or a slight variation. I
grabbed these in a few minutes off various pages:

GCC 2.0 __FUNCTION__
GCC 3.0 __func__ and __FUNCTION__
VS 2005 and VS.NET __FUNCTION__
Comeau __FUNCTION__
C++ BuilderX __FUNC__
HP 9000 ANSI C __func__
Digital Mars __func__, __FUNC__, and __FUNCTION__
OpenWatcom __func__ and __FUNCTION__

As a practical matter until C99 is more widely adopted, I'd probably use
__func__ in the code, but define __func__ to be __FUNCTION__. Then the code
is C99 correct and the preprocessor conditional can be removed without harm
in the future. For the compilers that don't define __FUNCTION__, I'd use
some compiler specific #ifdef's to define __func__ to a string or
appropriate extension.

#define __func__ __FUNCTION__
#if defined(OLD_COMPILER_A) || defined(OLD_COMPILER_B)
#undef __func__
#define __func__ "N/A"
#endif

//<insert valid code here>
printf("Function %s\n",__func__);
//<insert valid code here>


Rod Pemberton
 
G

Greg Comeau

Most compilers seem to support __FUNCTION__ or a slight variation. I
grabbed these in a few minutes off various pages:
...
Comeau __FUNCTION__

Yup. Actually, Comeau C/C++ can support __FUNCSIG__, __FUNCDNAME__,
__PRETTY_FUNCTION__,__FUNCTION__, and __func__, depending
upon the mode requested, and while I'm at it __BASE_FILE__ too. :)
 
O

Old Wolf

Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?

You could try:

char const __func__[] = "";

void foo()
{
if ( __func__[0] )
/* compiler supports it */;
}

The standard says that __func__ is defined as if it were declared
as a local array inside each function. So if you're lucky the
compiler may not declare it outside the function, so you get
away with this. (I haven't tried it).

Of course it's non-portable to declare your own identifier
containing a double underscore.
 
K

Keith Thompson

Old Wolf said:
Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?

You could try:

char const __func__[] = "";

void foo()
{
if ( __func__[0] )
/* compiler supports it */;
}

The standard says that __func__ is defined as if it were declared
as a local array inside each function. So if you're lucky the
compiler may not declare it outside the function, so you get
away with this. (I haven't tried it).

Of course it's non-portable to declare your own identifier
containing a double underscore.

I tried that. gcc reports a syntax error on the attempted declaration
of __func__. (The syntax error goes away if I change the declaration
to __func_.)
 
A

Ancient_Hacker

Hi,

Is there a clean way to determine at compile-time whether your compiler
supports the __func__ feature?

Good puzzle!

Since __func__ is a string variable, sort of, and you want to pass
this info to the
preprocessor, it sounds undoable.

You could kludge up a 2-pass test, something like this (untested):

cc -D_FUNCTEST_ prog.c
cc -DNOFUNC=$? prog.c


------ prog.c:

#ifdef _FUNCTEST_
char * foo = _func__;
#else

/* regular program */

#if NOFUNC
char * foo = "No function names available";
#else
char * foo = __func_;
#endif

#endif HAVEFUNC

#endif _FUNCTEST_
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top