P: n/a

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.  
Share this Question
P: n/a

Ashwani wrote:
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 400500 macros
#define Y(n,A) \
X FPP_MAP2(FPP_DUP(n,A),FPP_NCAR(FPP_SEQ_N0(),n),Y_)
#define Y_(A,i) \
A[i]
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.  
P: n/a

Laurent Deniau wrote:
Ashwani wrote:
>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[n1])
>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:
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.  
P: n/a

"Ashwani" <am****@yahoo.comwrote:
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  
P: n/a

Ashwani wrote:
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.  
P: n/a

Ashwani wrote:
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 notyetC99 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 C99style function prototype above looses nothing and avoids the use
of <stdargs.hmacros.  
P: n/a

Martin Ambuhl wrote:
Ashwani wrote:
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 notyetC99 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.   This discussion thread is closed Replies have been disabled for this discussion.   Question stats  viewed: 1114
 replies: 6
 date asked: Dec 21 '06
