a question about macro

E

ethan

Hi All,

I'd like ask some question about macro.
If I define a variable set, such as {5, 2, 10} or {1,3}.

#define X {5,2,10}

1) Is it possible to write a macro to get the number of items within X?

2) Is it possible to get the nth item within X?

e.g.

#define GET_N_ITEM(x, y) ....

GET_N_ITEM({3,2}, 2) is equal to 2.

Thank you very much.
 
W

Walter Roberson

I'd like ask some question about macro.
If I define a variable set, such as {5, 2, 10} or {1,3}.
#define X {5,2,10}

There isn't any such thing as a "variable set" in C.
The closest C comes to that is "initializers".
1) Is it possible to write a macro to get the number of items within X?

Not without dropping in some executable code, such as a temporary
assignment to a variable.

(sizeof (int _list_copy[] = X) / sizeof(int))
2) Is it possible to get the nth item within X?
e.g.
#define GET_N_ITEM(x, y) ....
GET_N_ITEM({3,2}, 2) is equal to 2.

Not without dropping in some executable code.


There are no list constructs that have independant existance at the
preprocessor level. In C89 at least, you cannot even ask how many
parameters were passed to a macro [but then, C89 doesn't allow any
variation in the number of parameters passed.]
 
E

ethan

If I can't write a macro such that get specified item within a define
{x, y, ..., z}, is any other approach can meet such requirement as
follow?

1) I wish there's a some kind of variable set including a set of
positive integer, and it would vary by product.

2) I wish to get some information, such as number of items or value of
the nth item, at the preprocessor level.

How should I do? Thank you very much.
 
W

Walter Roberson

If I can't write a macro such that get specified item within a define
{x, y, ..., z}, is any other approach can meet such requirement as
follow?
1) I wish there's a some kind of variable set including a set of
positive integer, and it would vary by product.

I don't think I understand what you are asking there.

2) I wish to get some information, such as number of items or value of
the nth item, at the preprocessor level.
How should I do?

I am certain that you cannot do either of those in C89, and
I think it very unlikely you could do it with C99 (but I don't
know C99 as well.)

The preprocessor has no notion at all of "set" or "list" or "array" or
anything even remotely similar. ALL that the preprocessor knows about
is "identifiers" and constants and operators applied to those.

The rules of evaluation of expressions in the preprocessor are pretty
simple: keep replacing macros until you get to a constant or to an
operator or to an identifier that cannot be further macro expanded;
replace defined(name) with a 0 if the name is not defined and a 1 if
the name is defined. If you are within a #if then replace each
identifier (or keyword!) that is left with 0 and evaluate the constant
expression; if you aren't within a #if then whatever was left is
code to be placed at that point.

There is no possibility at all in this evaluation sequence for
indexing or counting.


What you *can* do is something like

#define _l1_1 x
#define _l1_2 y
#define _l1_3 z
#define _l1_4 a
....
#define _l1_26 w

#define _J4(a,b,c,d) a ## b ## c ## d
#define get_nth(var,N) _J4(_,var,_,N)

After that, get_nth(l1,3) would be _l1_3 which would be z .

This isn't array indexing: this is just taking advantage of the
manner in which the preprocessor builds tokens and substitutes
them. It's purely a text-processing trick.


Depending on exactly what you are trying to do, here's a
different approach:

#include <stdio.h>
#define a1(a,b,c) a
#define a2(a,b,c) b
#define a3(a,b,c) c
#define sel3(L, N) (N == 1) ? a1(L) : (N == 2) ? a2(L): a3(L)
#define R 4,1,5
#define T 2,4,6
int main(void) {
printf( "%d\n", sel3(R,1) );
printf( "%d\n", sel3(R,2) );
printf( "%d\n", sel3(R,3) );
printf( "%d\n", sel3(T,1) );
printf( "%d\n", sel3(T,2) );
printf( "%d\n", sel3(T,3) );
return 0;
}


This is completely different from the get_nth approach: sel3(R,1) will
expand *in the code* to (1 == 1) ? 4 : (1 == 2) ? 1: 5
This expression will not be evaluated at the preprocessor level --
not unless you are within a #if .
 
D

Dave Thompson

There isn't any such thing as a "variable set" in C.
The closest C comes to that is "initializers".
Or in C99 compound literals, or already in GNU C that the equivalent.
1) Is it possible to write a macro to get the number of items within X?

Not without dropping in some executable code, such as a temporary
assignment to a variable.

(sizeof (int _list_copy[] = X) / sizeof(int))
That doesn't work, you can't assign an array at all, and sizeof can't
take a declaration, only an expression or typename. You can initialize
an array in a declaration, which at least for auto is executable.

You can just define a variable which you don't use, which doesn't need
to be and shouldn't be auto, and count it:
{ /* in whatever scope handy, 'global'=file if you like */
static /* probably */ int how_many [] = X;
count = sizeof how_many / sizeof (int);
/* since this evaluates at compile time, if there is no other use
of how_many a decent compiler will optimize it away */
}

In C99 you can also do a compound literal, which you similarly don't
(can't) use otherwise:
count = sizeof (int []) X /* is { list } */ / sizeof (int);
2) Is it possible to get the nth item within X?
e.g.
#define GET_N_ITEM(x, y) ....
GET_N_ITEM({3,2}, 2) is equal to 2.

Not without dropping in some executable code.


There are no list constructs that have independant existance at the
preprocessor level. In C89 at least, you cannot even ask how many
parameters were passed to a macro [but then, C89 doesn't allow any
variation in the number of parameters passed.]

Even in C99 you can't _ask_, you can only (try to) take all the rest.

- David.Thompson1 at worldnet.att.net
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top