The C standard (§ 6.10.3 p. 10) accepts variadic macros in 2 different forms:
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
While the first form works fine with Pelles C, the second form yields: error #1053: Disagreement in number of macro arguments
E. g.:
#include <stdio.h>
#include <string.h>
#define arg_and_ellipsis(arg, ...) \
{\
if (!strlen(#__VA_ARGS__)) \
printf("1 argument passed: %s\n", arg); \
else \
printf("more than 1 argument passed: %s %s\n", arg, #__VA_ARGS__); \
}
int main(void)
{
arg_and_ellipsis("arg_1");
arg_and_ellipsis("arg_1", "arg_2");
}
//The example below works
//The idea is taken here: https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
#include <stdio.h>
#define ARGS_COUNT(...) _ARGS_COUNT3(_ARGS_COUNT_EMPTY(__VA_ARGS__), __VA_ARGS__)
#define _ARGS_COUNT3(_1,...) _ARGS_COUNT4(_1,__VA_ARGS__)
#define _ARGS_COUNT4(_1,...) _ARGS_COUNT##_1(__VA_ARGS__)
#define _ARGS_COUNT(...) _ARGS_COUNT2(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _ARGS_COUNT0(...) _ARGS_COUNT2(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0)
#define _ARGS_COUNT2(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15, ...) _15
#define _ARGS_COMMA(...) ,
#define _ARGS_COUNT_EMPTY(...) _ARGS_COUNT_EMPTY1(__VA_ARGS__,)
#define _ARGS_COUNT_EMPTY1(_1,...) _ARGS_COUNT_EMPTY2(_ARGS_COMMA##_1())
#define _ARGS_COUNT_EMPTY2(...) _ARGS_COUNT_EMPTY3(__VA_ARGS__,0,,)
#define _ARGS_COUNT_EMPTY3(_1,_2,_3,...) _3
int main(int argc, char *argv[]) {
printf("()=%i\n",ARGS_COUNT());
printf("(1,2,3)=%i\n",ARGS_COUNT(1,2,3));
printf("(,)=%i\n",ARGS_COUNT(,));
printf("(5)=%i\n",ARGS_COUNT(5));
printf("(6,)=%i\n",ARGS_COUNT(6,));
return 0;
}
Thanks, Prokrust, for your suggestion.
In my eyes, this seems to be a workaround a little bit too convoluted.
As far as I understand the C standard, I have met a compiler bug which I just wanted to report.
By the way, the code provided by me works fine with GCC.
Werner
no problem with clang
first-aid
arg_and_ellipsis("arg_1",);
BTW
SrcFileCC2 Add-In for v9, a second opinion (https://forum.pellesc.de/index.php?topic=8107.msg29671#msg29671)
Thank you very much for your advice, TimoVJL!
This works, but nevertheless I consider the reported behavior a bug--or am I mistaken?
Anyway, there is also no problem with GCC.
Werner
Not a bug. You must specify something for __VA_ARGS__ (this has been debated, and could possibly change in some future C standard, but right now this is how it's supposed to work for C).
After re-reading the standard several times, I must admit that you are right, Pelle.
§ 6.10.3 p. 4, 2nd sentence, and § 6.10.3 p. 12, 2nd sentence, of the C standard arguably confirm this.
Although, in my personal opinion, not only some textbooks and a lot of posts on the Internet, but also the wording of the standard itself might be somewhat confusing.
Anyway, I apologize for the inconvenience caused!
Werner
No problem, and I agree this isn't the best part of the C standard...