How can I tokenize and strize the __func__ macro in C? - c

I want to tokenize and strize, with macros, the name of the function we are in, to overload the function (with dlopen()), in C.
I found similar things with __LINE__ and __FILE__, but it seems to be a bit different in the case with __func__...
I tried that:
#define OVERLOAD2(f) printf("Trying to overload function %s...", #f)
#define OVERLOAD1(f) OVERLOAD2(f)
#define OVERLOAD OVERLOAD1(__func__)
int main() {
OVERLOAD;
}
Compiling with different standards of compilation (c99, gnu11) doesn't change the result; instead of printing:
Trying to overload function main...
It prints:
Trying to overload function __func__...
How can I correct those macros?

Here is what the C11 draft says about __func__:
1 The identifier __func__ shall be implicitly declared by the
translator as if, immediately following the opening brace of each
function definition, the declaration
static const char __func__[] = "function-name";
As you see __func__, unlike __FILE__ and __LINE__, is no preprocessor macro, so you can't evaluate it during the preprocessing stage.
But in your code, you don't even need to do that. Just change
#define OVERLOAD2(f) printf("Trying to overload function %s...", #f)
to
#define OVERLOAD printf("Trying to overload function %s...", __func__)
as you can see in the standard's description of __func__, it's already a string. No need to stringize it.
If you need the function name as a "bare word" at compile time, e.g. an implicit #define __FUNC__ myfunc, you're out of luck.
It's not possible in standard C. GCC additionally provides __FUNCTION__, but despite its all-caps name, the GCC manual says:
Neither of them is a macro; the preprocessor does not know the name of
the current function.
MSVC provides __FUNCTION__ as a macro but it's defined to a string and you can't strip away the double quotes.
Only way around that is writing your own preprocessor or rethink your approach

Related

Stringinize and concat macro parameters correctly [duplicate]

This question already has answers here:
Treating __func__ as a string literal instead of a predefined identifier
(4 answers)
Closed 4 years ago.
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 ?
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__);.

Do function like macros need a mandatory parentheses? I am confused after referring the GCC cpp manual

Here is what confuses me:
To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.
I believe this is to make the code stand out for people other than the author of the program. Like other rules of CAPS for macro names. But the following is where I get confused:
A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.
I disagreed instantly after reading it. And gcc -E verified that in the following code
#define FUNC display()
void display()
{
printf("Display\n");
}
int main()
{
FUNC;
return 0;
}
The pre-processed output shows the content of the main() function as expected:
int main()
{
display();
return 0;
}
So what am I missing here? The pre-processor is for tokenizing the source, the macro expansion is a token and the above code was processed that way, the pre-processor isn't supposed to check anything or verify anything, it just dumps tokens. In that case what is the gcc manual trying to convey.
I am learning C programming, so I might be misunderstanding it a great deal as it frequently happens, I searched for a proper explanation and finally resorted to asking here. Please help me with this.
When you define:
#define FUNC display()
FUNC is not a function-like macro; it is an object-like macro that expands to a function call.
A function-like macro looks like:
#define FUNC() display()
Now you must write FUNC() to invoke it. Or, more frequently, it will have arguments:
#define MIN(x, y) ((x) > (y) ? (x) : (y))
and that can be invoked with:
int min = MIN(sin(p), cos(q));
with cautions about the number of times the arguments are expanded.
See also getc() as macro and C standard library function definition. It includes the standard's explanation of why it is important that the simple name of a function-like macro without a following open parenthesis is not expanded, which is what the quote from the GCC manual is telling you.
When a function-like macro is defined, the open parenthesis must 'touch' the macro name:
#define function_like(a) …
#define object_like (…)
Because there's a space after object_like, the open parenthesis is part of the replacement text, not the start of an argument list. When the function-like macro is invoked, there may be spaces between the macro name and the argument list:
function_like (x) // Valid invocation of function_like macro.
However, if you wrote:
int (function_like)(double a) { return asin(a) + 2 * atanh(a); }
this is not an invocation of the function-like macro because the token after function_like is not an open parenthesis.
There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as const from an older compiler that does not understand it. However, the preprocessor operator can never be defined as a macro, and C++'s named operators cannot be macros when you are compiling C++.

Treating __func__ as a string literal instead of a predefined identifier

I am using gcc to compile C99 code. I want to write a macro which will return a string containing the function name and line number.
This is what I have:
#define INFO_MSG __FILE__ ":"__func__"()"
However, when I compile code which attempts to use this string, for example:
char buff[256] = {'\0'}
sprintf(buff, "Something bad happened here: %s, at line: %d", INFO_MSG, __LINE__);
printf("INFO: %s\n", buff);
I get the following error message:
error: expected ‘)’ before ‘__func__’
I have tracked the problem down to the macro. as when I remove __func__ from the macro, the code compiles correctly.
How do I fix the macro, so that I can include the predefined __func__ macro in my string?
Judging from your comments, the objective is to have a macro which combines the file name and function name (and maybe line number) into a single string that can be passed as an argument to functions such as printf() or strcpy() or syslog().
Unfortunately, I don't think that's possible.
The C11 standard says:
ISO/IEC 9899:2011 §6.4.2.2 Predefined identifiers
¶1 The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
static const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function.
Therefore, __func__ is not a macro, unlike __FILE__ or __LINE__.
The related question What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? covers some alternative names. These are GCC-specific extensions, not standard names. Moreover, the GCC 4.8.1 documentation says:
These identifiers are not preprocessor macros. In GCC 3.3 and earlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string literals; they could be used
to initialize char arrays, and they could be concatenated with other string literals. GCC
3.4 and later treat them as variables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ have always been variables.
There are sound reasons why these cannot be preprocessor constructs. The preprocessor does not know what a function is and whether the text it is processing is in the scope of a function, or what the name of the enclosing function is. It is a simple text processor, not a compiler. Clearly, it would be possible to build that much understanding into the preprocessor (solely for the support of this one feature), but it is not required by the standard, and neither should it be required by the standard.
Unfortunately, though, I think it means that attempts to combine __func__ (by any spelling) with __FILE__ and __LINE__ in a single macro to generate a single string literal are doomed.
Clearly, you can generate the file name and line number as a string using the standard two-step macro mechanism:
#define STR(x) #x
#define STRINGIFY(x) STR(x)
#define FILE_LINE __FILE__ ":" STRINGIFY(__LINE__)
You can't get the function name into that as part of a string literal, though.
There are arguments that the file name and line number are sufficient to identify where the problem is; the function name is barely necessary. It is more cosmetic than functional, and slightly helps programmers but not other users.
After a quick experiment I found that you cannot use __func__ with stringification. It would not make much sense if you could as this would mean that the value would be wherever the macro is defined instead of where it is applied.
The nature of __func__, as noted in the comments on the question, is described in this answer.
Stringification is performed at pre-processor time and because of that __func__ is unavailable as it is essentially a function local string that is defined later on the compilation process.
However you can use __func__ in a macro as long as you don't use stringification on it. I think the following performs what you're after:
#include <stdio.h>
#define INFO_MSG "Something bad happened here: %s : %s(), at line: %d", \
__FILE__, __func__, __LINE__
int main()
{
char buff[256] = {'\0'};
sprintf(buff, INFO_MSG);
printf("INFO: %s\n", buff);
return 0;
}
Note that there's no particular reason, in the question as presented, to use a string buffer. The following main function would achieve the same effect without the possibility of buffer overrun:
int main()
{
printf("INFO: ");
printf(INFO_MSG);
printf("\n");
return 0;
}
Personally, I'd wrap up the whole process in the macro like this:
#include <stdio.h>
#define INFO_MSG(msg) printf("%s: %s : %s(), at line: %d\n", \
msg, __FILE__, __func__, __LINE__)
int main()
{
INFO_MSG("Something bad happened");
return 0;
}
Remark that, "__func__ is not a function so it cannot be called; in fact, it is a predefined identifier that points to a string that is the name of the function, and is only valid inside the scope of a function." - Jonathan.
The following is what you are looking for:
#define TO_STR_A( A ) #A
#define TO_STR( A ) TO_STR_A( A )
#define INFO_MSG TO_STR( __LINE__ ) ":" __FILE__
char buff[ 256 ] = { 0 };
sprintf( buff, "Something bad happened here, %s in function %s().", INFO_MSG, __func__ );
printf( "INFO: %s\n", buff );
... note that a call to __func__ can be made inside the function itself. See this.
it is a syntax error. I try to come over with your macro specification but I didnt find a efficient way, so maybe you can try this:
#define INFO_MSG __FILE__ , __FUNCTION__
int main()
{
char buff[256] = {'\0'};
sprintf(buff, "Something bad happened here: %s : %s(), at line: %d", INFO_MSG, __LINE__);
printf("INFO: %s\n", buff);
}

What does this #define syntax mean?

I came across this one, don't understand.
#define IDEBUG(a...)
What does the "(a...)" mean?
That's a variadic macro.
Quoting verbatim from the linked page:
A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example:
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
This kind of macro is called variadic. When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument. This sequence of tokens replaces the identifier VA_ARGS in the macro body wherever it appears. Thus, we have this expansion:
eprintf ("%s:%d: ", input_file, lineno)
==> fprintf (stderr, "%s:%d: ", input_file, lineno)
And for that specific form, quoting further down in the page:
If your macro is complicated, you may want a more descriptive name for the variable argument than __VA_ARGS__. CPP permits this, as an extension. You may write an argument name immediately before the `...'; that name is used for the variable argument. The eprintf macro above could be written
#define eprintf(args...) fprintf (stderr, args)
Variable number of parameters. See variadic macros
It is a variadic macro.
A variadic macro is a macro that accepts a variable number of arguments. The feature has been introduced in C99.
The form
#define IDEBUG(a...) printf(a)
with the parameter a... is a GNU extension, a gives a name to the __VA_ARGS__ identifier.
The standard C99 form would be
#define IDEDBUG(...) printf(__VA_ARGS__)

Can I substitute __func__ into an identifier name in a C macro?

I'd like to write a C macro which takes this:
int foo() {
MY_MACRO
}
and expands it to this:
int foo() {
_macro_var_foo++;
}
I've found that I can't use __func__, because that doesn't actually get expanded in the macro; it's treated by the preprocessor like a variable.
Is there some way to get this to work?
The preprocessor doesn't know about functions, just source files and line numbers. At that stage it's not performing syntactical analysis, just textual analysis and substitutions. That's why __func__ is a magical variable instead of a magical macro like __FILE__ and __LINE__.
In the C99 standard, __func__ is given a special new category of 'predefined identifier' (in section 6.4.2.2 Predefined Identifiers):
The identifier __func__ shall be implicitly declared by the translator as if,
immediately following the opening brace of each function definition, the declaration
static const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function
This means that it is out of the scope of the C preprocessor, which is not aware of function boundaries or function names. Further, it would expand to a string, which makes it inappropriate for embedding into a variable name.
The GCC (4.4.1) manual says in section 5.43 (Function Names as Strings):
These identifiers [meaning __func__, __FUNCTION__ and __PRETTY_FUNCTION__] are not preprocessor macros. In GCC 3.3 and earlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string literals; they could be used
to initialize char arrays, and they could be concatenated with other string literals. GCC
3.4 and later treat them as variables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ have always been variables.
If there was a way to get the function name into a preprocessor cleanly, then it is probable that the documentation here would have cross-referenced it, if it did not define it.
Technically, the answer to your question is "yes", there is "some way". But I think you already knew that, and it's true that you cannot deal with this at the macro preprocessor level.
Sure, there is always a way, you just might need a really long tape on that Turing Machine.
I think you already know this, but for the record you can get the overall result you want with:
#define MY_MACRO f_dictionary(__func__, ADDONE);
So now, you just need to implement f_dictionary and an ADDONE op for it.
You can do this using token concatenation.
#define MY_MACRO(baz) _macro_var_##baz++;
#define FUNC_WRAPPER(bar)\
int bar()\
{\
MY_MACRO(bar)\
}
FUNC_WRAPPER(foo)
The output from gcc -E:
int foo(){ _macro_var_foo++;}
Version dealing with argument lists using variadic macros and x macros:
#define MY_MACRO(baz) _macro_var_##baz++;
#define FUNC_DEF(ret_type,bar,...)\
ret_type bar(__VA_ARGS__)\
{\
MY_MACRO(bar)\
FUNC_CONTENTS\
}
#define FUNC_CONTENTS\
printf("Do some stuff\n", s1, s2);
FUNC_DEF(int, foo, char *s1, char *s2)
#undef FUNC_CONTENT

Resources