need a macro

A

Ashwani

consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
the number of valid strings in A, and it in turns calls X.

So at all the places in the code where X is getting called I would use
Y(n, A) as generic call. What would Y be like?

Please note that I cannot control the way X is written, it is a 3rd
party code.
 
L

Laurent Deniau

Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is

I assume here that you mean X(A[0], A[1], A[2], A[3]....A[n]) as above
the number of valid strings in A, and it in turns calls X.

This is not possible unless n is a literal integer constant (e.g. 3).
So at all the places in the code where X is getting called I would use
Y(n, A) as generic call. What would Y be like?

Assuming that n is a literal integer constant, a simple solution would be:

#define Y(n,A) \
X(Y_##n(A))

#define Y_0(a) a[0]
#define Y_1(a) Y_0(a),a[1]
#define Y_2(a) Y_1(a),a[2]
#define Y_3(a) Y_2(a),a[3]
#define Y_4(a) Y_3(a),a[4]
....
#define Y_126(a) Y_125(a),a[126]

Otherwise a computed solution would require a 3rd party cpp lib (you
will have less to write, but more macros defined):

#include <fpp.h> // my cpp lib, not standard, load about 400-500 macros

#define Y(n,A) \
X FPP_MAP2(FPP_DUP(n,A),FPP_NCAR(FPP_SEQ_N0(),n),Y_)
#define Y_(A,i) \
A

Y(3,a) -> X(a[0],a[1],a[2])

(FPP_SEQ_N0() generate a list of integers starting at 0)

hope this help.

a+, ld.
 
L

Laurent Deniau

Laurent said:
Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
I assume here that you mean X(A[0], A[1], A[2], A[3]....A[n]) as above

Sorry, if n is the number of valid strings, then it should be:

X(A[0], A[1], A[2], A[3]....A[n-1])
This is not possible unless n is a literal integer constant (e.g. 3).


Assuming that n is a literal integer constant, a simple solution would be:

With the corrected version:
#define Y(n,A) \
X(Y_##n(A))

#define Y_1(a) a[0]
#define Y_2(a) Y_1(a),a[1]
#define Y_3(a) Y_2(a),a[2]
#define Y_4(a) Y_3(a),a[3]
#define Y_5(a) Y_4(a),a[4]
...
#define Y_127(a) Y_126(a),a[126]

Y(3,a) -> X(a[0],a[1],a[2])

a+, ld.
 
R

Richard Bos

Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I presume this is a variadic function?
I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
the number of valid strings in A, and it in turns calls X.

So at all the places in the code where X is getting called I would use
Y(n, A) as generic call. What would Y be like?

In the general case, this is not possible. You can write hacks for
specific cases, but unfortunately there is no ISO C way to construct a
variable argument list at run time.

Richard
 
L

Laurent Deniau

Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
the number of valid strings in A, and it in turns calls X.

So at all the places in the code where X is getting called I would use
Y(n, A) as generic call. What would Y be like?

Please note that I cannot control the way X is written, it is a 3rd
party code.

Note that if n is not a constant literal, you can still use a wrapper
function like:

void Y(int n, char *A[])
{
switch(n) {
case 0: break;
case 1: X(A[0]); break;
case 2: X(A[0],A[1]); break;
...
case 127: X(A[0], .., A[126]); break;
default: abort();
}
}

If speed matters for small size you can do:

static inline void Y(int n, char *A[])
{
extern void Y_(int,char**);

switch(n) {
case 0: break;
case 1: X(A[0]); break;
case 2: X(A[0],A[1]); break;
case 3: X(A[0],A[1],A[2]); break;
default: Y_(n,A);
}
}

where Y_ is equivalent to the first Y above without the 4 first cases.

After optimisation, Y(2,A) will be equivalent to X(A[0],A[1]) and Y(4,A)
to Y_(4,A) but Y(n,A) will inline the code of Y including the call to
Y_. For n>3 the extra function call is probably negligeable.

a+, ld.
 
M

Martin Ambuhl

Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
the number of valid strings in A, and it in turns calls X.

C99 compilers, and several not-yet-C99 compilers when not invoked for
C90 (or C89) compliance, offer the ability to declare X as
X_return_type X(size_t n, char *array[n]);
If you have such a compiler, you need no such macro.

BTW, your function as you described it cannot work. Functions with a
variable number of arguments need an initial segment specifying a known
argument. That is
X_return_type X( ... );
is not a legal prototype, Since you must have something like
X_return_type X(size_t n, ...);
the C99-style function prototype above looses nothing and avoids the use
of <stdargs.h> macros.
 
G

Guest

Martin said:
Ashwani said:
consider A is of type char *A[]
there is this function X which takes variable number of "char * "
arguments, so X can be called like

X (A[0]) or
X(A[0], A[1]) or
X(A[0], A[1], A[3]) and so on

I have to call this function X from different places in the code.

But I want to make the calling of X as generic as possible so I would
like to have a wrapper function or a macro Y such that instead of
calling X( A[1], A[2], A[3]....A[n]) I would call Y(n, A) where n is
the number of valid strings in A, and it in turns calls X.

C99 compilers, and several not-yet-C99 compilers when not invoked for
C90 (or C89) compliance, offer the ability to declare X as
X_return_type X(size_t n, char *array[n]);
If you have such a compiler, you need no such macro.

This is equivalent to

X_return_type X(size_t n, char *array[]);

except for a gratuitous incompatibility with C90.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top