Reputation: 177
I want to create one macro that will work differently in case when it HAS parameters or NOT.
For example: there are two different implementation of printing error:
// 1. Print message = check code
#define PRINT_IF(wasError) \
do { if (wasError) printf(#wasError); } while(false)
// 2. Throws an exception with formatted message
#define PRINT_TEXT_IF(wasError, format, ...) \
do { if (wasError) printf(format, ##__VA_ARGS__); } while(false)
And I'd like to have one macro for both cases.
What I've tried is create a global macro that checks if it has parameter or not, based on approach from How to count the number of arguments passed to a function that accepts a variable number of arguments?.
#define RANDOM_GUID "5c300a82-2fe8-4bd3-ad12-ef13fa7b4a82"
#define FIRST_ARG(a1, ...) a1
#define HAS_ARGS(...) FIRST_ARG(##__VA_ARGS__, RANDOM_GUID)
#define GLOBAL_PRINT_IF(wasError, ...) \
do { \
if (wasError) { \
if (HAS_ARGS(##__VA_ARGS__)==RANDOM_GUID ) \
PRINT_IF(wasError); \
else \
PRINT_TEXT_IF(wasError, __VA_ARGS__); \
} \
} while(false)
I assume that because FIRST_ARG
always return first argument, it will return RANDOM_GUID
if ##__VA_ARGS__
are empty.
But this code doesn't compile with error: pasting "." and "red" does not give a valid preprocessing token.
I've tried to play with ##
before __VA_ARGS__
, but it fails with expected primary-expression before ‘==’ token
in line
if (HAS_ARGS(__VA_ARGS__)==RANDOM_GUID )
So, what am I doing wrong? How to deal with it properly?
Upvotes: 1
Views: 642
Reputation: 2326
And this snippet returns the number of argument event if this is 0:
#include <stdio.h>
#define PRINT(...) (printf("%d\n", sizeof((int[]){__VA_ARGS__})/sizeof(int)))
int main(void)
{
PRINT();
PRINT(1,1);
PRINT(1,1,1,1);
return 0;
}
so easily, this second snippet does the job
#include <stdio.h>
#define PRINT(...) (((sizeof((int[]){__VA_ARGS__})/sizeof(int))==0)?printf("do A\n"):printf("do B\n"))
int main(void)
{
PRINT();
PRINT(1,1);
PRINT(1,1,1,1);
return 0;
}
Upvotes: 1