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.
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 .