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__);.
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.
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 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);
}
This question already has answers here:
How to define macro function which support no input parameter and support also input parametr in the same time
(4 answers)
Overload C macros
(2 answers)
Closed 8 years ago.
Is there any way to define macro which can have one or zero parameters?
I need something to be used as in this example:
#define MY_RETURN(ret) return ret;
void foo(){
MY_RETURN();
}
int foo_integer(){
MY_RETURN(1);
}
I am not able to find solution for this.
In C99 and later, it is possible to use variadic macros.
C11 (n1570), § 6.10 Preprocessing directives
# define identifier lparen identifier-list , ... ) replacement-list new-line
Your macro may look something like:
#define MY_RETURN(...) return __VA_ARGS__
If you need to count arguments, you may check here for instance.
Define two MY_RETURN macros, one with parameter and one without! A kind of overloading, but for macros.
Based on the answer of How to define macro function which support no input parameter and support also input parametr in the same time
Consider something like this:
#define MY_RETURN(ret) { \
int args[] = {ret}; \
if(sizeof(args) > 0) \
return ret; \
}
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