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);
}
Related
I'm writing DEBUG_MSG for print debug messages
#define DEBUG_MSG(msg_str) _DEBUG_MSG_GENERIC(msg_str)
The _DEBUG_MSG_GENERIC is because I'd like to:
Show int message when a input parameter is int
Show char* message when a input parameter is char*
and its implement:
#define _DEBUG_MSG_GENERIC(strs) \
_Generic( (strs), \
int: _DEBUG_MSG_INT, \
default: _DEBUG_MSG_STR \
)(strs)
Now I'd like to implement _DEBUG_MSG_INT and _DEBUG_MSG_STR with Macro function and printf :
#define _DEBUG_MSG_INT(val) printf("%d\n", val);
#define _DEBUG_MSG_STR(str) printf("%s\n", str);
But I got error message is:
main.c:14:30: error: ‘_DEBUG_MSG_INT’ undeclared (first use in this function); did you mean ‘DEBUG_MSG’?
14 | int: _DEBUG_MSG_INT, \
| ^~~~~~~~~~~~~~
How do I solve it?
Does _generic only support function(pointer to function) and not support macro function?
Full Code
#include <stdio.h>
#define DEBUG_MSG(msg_str) _DEBUG_MSG_GENERIC(msg_str)
#define _DEBUG_MSG_GENERIC(strs) \
_Generic( (strs), \
int: _DEBUG_MSG_INT, \
default: _DEBUG_MSG_STR \
)(strs)
#define _DEBUG_MSG_INT(val) printf("%d\n", val)
#define _DEBUG_MSG_STR(str) printf("%s\n", str)
int main()
{
DEBUG_MSG("str");
DEBUG_MSG(5);
}
The problem is that both _DEBUG_MSG_INT and _DEBUG_MSG_STR are function-like macros thus they are only expanded if they are followed by ().
Note that macro expansion takes place before actual C compilation thus _Generic is nothing more than a common identifier at preprocessor stage.
I suggest using _Generic not for selection of the function pointer but rather for a formatting specifier to be used in printf(). Try:
#define _DEBUG_MSG_GENERIC(arg) printf( _DEBUG_MSG_FMTSPEC(arg), arg)
#define _DEBUG_MSG_FMTSPEC(arg) \
_Generic( (arg), int: "%d\n", default: "%s\n")
I believe your issue is because the preprocessor only makes one pass of the source code, so the printf's don't get substituted.
A quick solution would be to define _DEBUG_MSG_INT(val) and _DEBUG_MSG_STR(str) as real functions like so:
void _DEBUG_MSG_INT(int val) {
printf("%d\n", val);
}
void _DEBUG_MSG_STR(char * str) {
printf("%s\n", str);
}
The compiler will optimise out the extra function call overhead and will behave as if you called printf directly.
_Generic is not a preprocessor operation and cannot be used to select preprocessor macro functions. The code after a : in its cases must be a C expression (specifically an assignment-expression).
The code you have in those positions is _DEBUG_MSG_INT and _DEBUG_MSG_STR. Those are preprocessor macro names.
Those preprocessor macros are function-like macros. They are macro-replaced only when they are followed by a (. In your code, there is no ( after them, so they are not replaced.
That means the code after reprocessing looks like int : _DEBUG_MSG_INT,. So the compiler attempts to interpret _DEBUG_MSG_INT as an expression. Since _DEBUG_MSG_INT is not a declared identifier, the compiler reports an error that it is undeclared.
In summary, your code _Generic( (strs), int: _DEBUG_MSG_INT, default: _DEBUG_MSG_STR )(strs) attempts to use an after-preprocessing _Generic selection to select a preprocessing-time macro (either _DEBUG_MSG_INT or _DEBUG_MSG_STR) and then to have that macro treated as a function-like macros with the (strs) that appears after the _Generic. That simply cannot work; an after-preprocessing _Generic cannot select preprocessing macro names.
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__);.
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
I was playing with a macro to enable/disable traces when I came out with the following code when the macro is disabled:
int main()
{
("Hello world");
}
This code is valid and I got the desired effect (nothing happens when the macro is disabled) but I couldn't figure out what exactly is happening. Is the compiler seeing the parenthesis as a "nameless" method declaration?
To make it clearer the code is :
#ifdef TRACE
#define trace printf("%s %d -> ",__FILE__, __LINE__);printf
else
#define trace
#endif
int main()
{
trace("Hello world");
}
Thanks in advance.
If the function name is missing, as in your first example, then it is not a "parenthesis operator". It is simply a syntactic element of an expression that alters the association between operators and operands. In this case it simply does nothing. What you have is just an expression
"Hello world";
which evaluates to a value of char * type, and that value is ignored. You can surround that expression in a redundant pair of ()
("Hello world");
which will not change anything.
In exactly the same way you can write
(5 + 3);
in the middle of your code and get an expression that evaluates to value 8, which is immediately discarded.
Usually compilers generate no code for expression statements that have no side effects. In fact, in C language the result of every expression statement is discarded, so the only expression statements that "make sense" are expression statements with side effects. Compilers are normally fairly good at detecting effectless statements and discarding them (sometimes with a warning).
The warning could be annoying, so writing effectless expression statements like
"Hello world";
might not be a good idea. Typically compilers recognize a cast to void as a request not to generate this warning
(void) "Hello world";
So you might consider redefining your macro accordingly.
Of course, using the above trace technique, you have to remember that if you put something that does have a side effect as an argument for your macro
trace("%d\n", i++);
then in "disabled" form it will look as follows
("%d\n", i++);
(two subexpressions, chained by a comma operator into one expression). The side effect of incrementing i persists in this case, it does not get disabled. The whole thing is equivalent to plain
i++;
Also if you use a function call as an argument
trace(get_trace_name());
the "disabled" form will look as
(get_trace_name());
and the compiler might not be smart enough to realize that the call to get_trace_name() should be discarded. So, be careful when using your macro. Avoid arguments with side effects, avoid arguments with function calls, unless, of course, it is your intent to preserve the side effects when disabling the actual tracing.
Whether it works or not may depend on exactly what you pass as the arguments to the macro (see the side-effects issue mentioned by AndreyT). In this case it is benign. However the following is probably safer since it will result in no text being inserted when the macro is processed and TRACE is not defined:
#ifdef TRACE
#define trace printf("%s %d -> ",__FILE__, __LINE__);printf
#else
#define trace( ... )
#endif
assuming your compiler supports variadic macros. If it does the following would be a better definition perhaps:
#ifdef TRACE
#define trace( fmt, ...) printf("%s %d -> " fmt, __FILE__, __LINE__, __VA_ARGS__ ) ;
#else
#define trace( ... )
#endif
Note that the lack of a comma between "%s %d -> " and fmt is deliberate and required. Note also that the fmt argument must be a literal string constant in order for adjacent string literal concatenation to occur - a variable of any kind would generate an error, but it is bad practice to use a variable for a format specifier in any case.
("Hello world");
is an expression returning a constant pointer to a string. This value is not consumed.
Parenthesis have no specific role and you can omit them:
"Hello world";
#ifdef TRACE
#define trace printf("%s %d -> ",__FILE__, __LINE__);printf
#else
#define trace
#endif
int main {
trace("Hello world");
}
The way that macros work in C is that the compiler will (essentially)* do a literal replace of the identifier.
So in your case, there are two options depending on the value of the #IFDEF
trace("Hello world");
can become
printf("%s %d -> ",__FILE__, __LINE__);printf("Hello world");
or
("Hello world");
The first option is a sequence of valid C code which consists of two printf statements. The second option is a sequence of valid C code which consists of a string (char *) inside unnecessary braces.
If your compiler supports C99 (or you're using gcc which had this feature earlier) you can use variadic macros:
#ifdef TRACE
#define trace(...) printf("%s %d -> ",__FILE__, __LINE__);printf(__VA_ARGS__)
#else
#define trace(...)
#endif
This avoids the problems you can get with side-effects in arguments. If you have a strict C89 compiler, you've got to just avoid side-effects...
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