Hi!
Question's Background:
void dash(int *n, char c)
is to draw characters c separated by '+'.
Parameter n
is an array of ints, e.g. {1, 3, 2} and '-' for c
should give "+-+---+--+", which works fine.
To use dash I do {int f={1, 3, 2}; dash(f, '-');}
, which makes the construct copy&pastable.
The question itself:
To avoid copy&pasting I wanted to do #define F(X, Y) {int f=X; dash(f, Y);}
,
resulting in a nicely usable F({1, 3, 2}, '-')
.
Unfortunately the compiler complains about F getting 4 (array's length + 1) arguments instead of 2.
So how can you give {1, 3, 2}
as parameter to a macro?
views:
339answers:
5Variadic macros are a feature of C99.
#define F(Y,...) dash((int[]){__VA_ARGS__},Y)
So how can you give {1, 3, 2} as parameter to a macro?
F('-',1,3,2);
Instead of trying to use a macro to set up and make these calls, I'd probably consider changing the interface to dash()
to use varargs:
#include <stdarg.h>
void dash( char c, ...)
{
// ...
}
int main() {
dash( '+', 1, 3, 2, -1); // note: negative number indicates
// the end of the list of numbers
return 0;
}
Using varargs isn't the best thing in the world (they're difficult to use and aren't typesafe), but I think it would be better than the macro concoction you're trying to gen up.
Also, remember that even if you stick with your current interface for dash()
and come up with a macro that does what you want, you still need to have a way to indicate the end of the sequence of numbers to be passed into dash()
. Otherwise there's no way for dash to know when it has reached the end of the array. You have several choices:
- use a sentinel value, such as 0, -1, or any negative number (like in the vararg example above)
- pass the number of elements in the array as another argument
- set the size of the array as a part of
dash()
's interface. In your example,dash()
might require that an array of 3 ints be passed in. No more, no less (actually more would be OK - they just wouldn't be used). If you did this, fixing your macro would be much easier, but I suspect it's not how you want dash to behave.
Here is my version:
#include <stdio.h>
void dash(int len, int *n, char c){
int i;
printf("dash( %i, {", len );
for( i=0; i<len-1; i++ )
printf(" %i,", n[i] );
printf(" %i }, '%c')\n", n[i], c );
}
#define NOPAREN(...) __VA_ARGS__
#define F1(arr,char) { int f[]={NOPAREN arr}; dash(sizeof(f)/sizeof(f[0]),f,char); }
#define F2(char,...) { int f[]=__VA_ARGS__; dash(sizeof(f)/sizeof(f[0]),f,char); }
int main(void){
F1( (1,3,2), '-' );
F2( '-', {4,6,5} );
}
Result:
dash( 3, { 1, 3, 2 }, '-')
dash( 3, { 4, 6, 5 }, '-')
You can pass { 1, 3, 2 }
as an argument to a macro if you define { 1, 3, 2 }
as another macro
#define PARAMS { 1, 3, 2 }
F(PARAMS, '-')
#undef PARAMS
Unfortunately, there seems to be no direct way to do literally what you ask, i.e. pass specifically { 1, 3, 2 }
in this specific form. It might be worth switching to alternative methods, including the C99-specific ones suggested in other answers.