This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

The semantics of __FUNCTION__


Today, I discovered that __FUNCTION__ feature is being changed in
gcc-3. The old behaviour is described in the manual as

:    The compiler automagically replaces the identifiers with a string
: literal containing the appropriate name.  Thus, they are neither
: preprocessor macros, like `__FILE__' and `__LINE__', nor variables.
: This means that they catenate with other string literals, and that they
: can be used to initialize char arrays.  For example
: 
:      char here[] = "Function " __FUNCTION__ " in " __FILE__;

If I recall correctly, this wording is only a couple of months old,
and it was clarified after a manual-bug report by me.

Now, the manual goes on to say

:    Note that these semantics are deprecated, and that GCC 3.2 will
: handle `__FUNCTION__' and `__PRETTY_FUNCTION__' the same way as
: `__func__'.  `__func__' is defined by the ISO standard C99:

Why this crippling??? If I ever wanted the ISO C99 behaviour, I would
write __func__, not __FUNCTION__. But I don't want that, I
deliberately check for the existence of the gcc __FUNCTION__ feature
in my configure script, because that is what I want. If __FUNCTION__
is unavailable or broken, I'll use only __FILE__ and __LINE__.
__func__ simply doesn't do what I want.

The way I use it is to construct static strings at compile time that
describe a place in the program, and I use them for debugging
purposes. __FUNCTION__ is not essential to the working of the program
in any way, but it makes debugging easier.

For example,

  #if HAVE_GCC_FUNCTION
  # define FUNCTION_NAME __FUNCTION__
  #else
  # define FUNCTION_NAME "Unknown"
  #endif

  #define STRINGIZE1(x) #x
  #define STRINGIZE(x) STRINGIZE1(x)
  #define STRING_LINE STRINGIZE(__LINE__)

  ...

  #if DEBUG_ALLOC
  extern struct lsh_string *all_strings;
  
  struct lsh_string *lsh_string_alloc_clue(UINT32 size, const char
  *clue);

  #define lsh_string_alloc(size) \
    (lsh_string_alloc_clue((size), (__FILE__ ":" STRING_LINE ": "
    FUNCTION_NAME)))
  
  #else /* !DEBUG_ALLOC */
  struct lsh_string *lsh_string_alloc(UINT32 size);
  #endif /* !DEBUG_ALLOC */

To do the same thing with __func__ complicates things, I either have
to change all places where I store the debugging information to keep
the components separately. That's ugly, because a single const char *
is the appropriate abstraction for this kind of debugging information,
it can be printed out in the log and inspected from gdb. It is easily
passed around, the only one who needs to care for it's inner structure
is the one constructing the string. Or I have to construct the strings
at runtime, which implies a small but useless allocation and copying
overhead, and the general head-ache of deciding when to deallocate the
strings.

Please, please, please, PRETTY PLEASE change your mind.

I think it makes a lot of sense to have __FILE__ and __FUNCTION__
behave in a consistent way. Will you cripple __FILE__ in the same way
as you have done to __FUNCTION__? That would make things more
consistent, and also more painful.

Regards,
/Niels


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]