4

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
  • 1
    It's not clear how dash determines how many elements are in the array. Are there always 3? Commented Oct 29, 2009 at 15:45
  • I've implemented it to stop at the last Element, which has to be 0. But that wasn't important for the question itself, so i left it out here. Commented Oct 31, 2009 at 12:14

4 Answers 4

5

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);
Sign up to request clarification or add additional context in comments.

2 Comments

I think it should be #define F(Y, ...) dash((int []){VA_ARGS}, Y} Note the (int []) cast and the missing semicolon.
I personally like that answer best. I'll do it this way or with varargs in dash. THX everyone!
4

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

Comments

1

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.

Comments

0

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.

1 Comment

not practical but creative, I didn't think of this one

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.