NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

standards/51044: NetBSD cdefs.h defines __func__ incompatibly with C99



>Number:         51044
>Category:       standards
>Synopsis:       NetBSD cdefs.h defines __func__ incompatibly with C99
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    standards-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 05 10:00:00 +0000 2016
>Originator:     Bruce Lilly
>Release:        NetBSD 7.0
>Organization:
>Environment:
# uname -sr
NetBSD 7.0
>Description:

/*      $NetBSD: cdefs.h,v 1.121 2014/08/08 19:43:49 joerg Exp $        */
contains, starting ca. line 388:

/* 
 * C99 defines __func__ predefined identifier, which was made available
 * in GCC 2.95.
 */
#if !(__STDC_VERSION__ >= 199901L)
#if __GNUC_PREREQ__(2, 6)
#define __func__        __PRETTY_FUNCTION__
#elif __GNUC_PREREQ__(2, 4)
#define __func__        __FUNCTION__
#else
#define __func__        ""
#endif  
#endif /* !(__STDC_VERSION__ >= 199901L) */

When compiling with `clang -std=c89` or `clang -std=gnu89` this results in __func__ being defined as __PRETTY_FUNCTION__, which does not conform to C99 (C99 requires the *unadorned* (emphasis added) function name).
>How-To-Repeat:
This simple non-standard program shows (with `clang -v -std=c89 -E`) that the problem isn't with clang (clang provides a C99-compliant __func__):

--------- start program 1 ------------
extern int printf(const char *, ...);

int foo(int bar)
{
    return printf("%s\n", __func__);
}

int main(int argc, const char * const *argv)
{
    (void)printf("%s\n", __func__);
    return(foo(argc));
}
--------- end program 1 ------------

Using <stdio.h> causes the aforementioned cdefs.h to be included and results in non-conforming output.
------------- start program 2 -----------
#include <stdio.h>

int foo(int bar)
{
    return printf("%s\n", __func__);
}

int main(int argc, const char * const *argv)
{
    (void)printf("%s\n", __func__);
    return(foo(argc));
}
------------- end program 2 -----------

Leaving out the expansion of <stdio.h>, the preprocessed output ends with:
...
int foo(int bar)
{
    return printf("%s\n", __PRETTY_FUNCTION__);
}

int main(int argc, const char * const *argv)
{
    (void)printf("%s\n", __PRETTY_FUNCTION__);
    return(foo(argc));
}

This also shows up with `gcc -std=c90`, however clang __PRETTY_FUNCTION__ adorns the function name, whereas gcc (at least w/ v 4.8.4) does not.
>Fix:
Don't define __func__ as __PRETTY_FUNCTION__ (ever!)
Instead use the documented gcc work-around:
https://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Function-Names.html

That will work for both gcc and clang.



Home | Main Index | Thread Index | Old Index