-1

Basically, i have the following macro definition :

#include <stdio.h>

#define altErrMsg(x,y,z) x":"#y":"z
#define errMSG(x,y,z) altErrMsg(x,y,z)
#define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)

int
main (int argc, char **argv) 
{
    puts (__failure ());
    return 0;
}

The macro __failure() is supposed to print some debugging information in the form "filename:line:function". For this purpose i used the GCC's predefined macros __LINE__, __FILE__ and __FUNCTION__. I used an indirection so that the predefined macros will be expanded before they are concatenated. The expansion of __LINE__ must be stringized (using the # before the parameter's name).

AFAIK, __failure() will be expanded to somthing like : "test.c"":""20"":""main" which will be quoted into a one single string constant "test.c:20:main". But that's not happening, instead, I'm getting errors :

test.c:5:46: error: expected ‘)’ before ‘__FUNCTION__’
 #define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)
                                              ^
test.c:3:35: note: in definition of macro ‘altErrMsg’
 #define altErrMsg(x,y,z) x":"#y":"z
                                   ^
test.c:5:21: note: in expansion of macro ‘errMSG’
 #define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)
                     ^~~~~~
test.c:10:11: note: in expansion of macro ‘__failure’
     puts (__failure ());

Compiling with gcc -E shows that the __FUNCTION__ is never expanded and the final string looks like this : "test.c"":""22"":"__FUNCTION__ which is a wrong syntax but i have no idea why this happens !

Is there an explanation for this behavior ? and any correction to the issue ?

Karim Manaouil
  • 1,177
  • 10
  • 24
  • Note [C11 §7.1.3 Reserved identifiers](http://port70.net/~nsz/c/c11/n1570.html#7.1.3) and avoid using `__failure` as a name because it is unconditionally reserved for use by the implementation. – Jonathan Leffler Mar 07 '18 at 18:56

1 Answers1

1

If you ask why then from Predefined macros

C99 introduced __func__, and GCC has provided __FUNCTION__ for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function.

Not a macro - that's why not macro expanded. If this was your intention it won't work. (As you have seen).

Solution is to use a function where you will pass these things and print them accordingly. That would work.

void my_log( const char * filename, int linenumber, const char * funcname){
    fprintf(sdtout,"%s[%d]%s\n",filename, linenumber, funcname);
}

And call like my_log(__FILE__,__LINE__,__FUNCTION__);.

user2736738
  • 30,591
  • 5
  • 42
  • 56