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 isint
- Show
char*
message when a input parameter ischar*
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);
}
CodePudding user response:
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.
CodePudding user response:
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")