tags:

views:

339

answers:

5

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?

+2  A: 

Variadic 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);
Will
I think it should be#define F(Y, ...) dash((int []){__VA_ARGS__}, Y}Note the (int []) cast and the missing semicolon.
quinmars
good points, fixed
Will
thx, now I can give you +1
quinmars
I personally like that answer best. I'll do it this way or with varargs in dash. THX everyone!
spc-mrn
+1  A: 

Try F(({1, 3, 2}), '-')

Paul Baker
+1  A: 

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.
Michael Burr
A: 

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 }, '-')
sambowry
A: 

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.

AndreyT