public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* C preprocessor For loops ?
@ 2006-06-08 17:19 Jim Cromie
  0 siblings, 0 replies; only message in thread
From: Jim Cromie @ 2006-06-08 17:19 UTC (permalink / raw)
  To: gcc-help


#include <stdio.h>

/* explore ForX() macro expansion possibilities, mainly for use in
   array initialization expressions

   Want ForX(N, Do_Macro(X))
   - where param X in Do_Macro goes from 0..N (N is the value passed in)
    - domacro initializes fields in elements consistent with their 
position in the list.

   Breakdown:
   - create some fixed-N expanders,
   - add them up as needed.
   - each N-exander gets its starting-point

   Assumptions
   - ForX(N,Func) presumably is buildable for arbitrary N
   - it may have to emit the "struct a X[] = { }" part.

   Problems And Question areas
   - X <- N
   - scanning and rescanning
   - influence of #, ## on rescans
*/



#define Given(N, C99Expr...)    \
    [N] = { .index = N, C99Expr },

#define FOR_1(N, Rest...)    \
    Given(N, Rest)

#define FOR_2(N, Rest...)    \
    FOR_1(N, Rest)        \
    FOR_1(1+N, Rest)    \

#define FOR_4(N, Rest...)    \
    FOR_2(N, Rest)        \
    FOR_2(2+N, Rest)    \

#define FOR_8(N, Rest...)    \
    FOR_4(N, Rest)        \
    FOR_4(4+N, Rest)

#define FOR_16(N, Rest...)    \
    FOR_8(N, Rest)        \
    FOR_8(8+N, Rest)

#define FOR_32(N, Rest...)    \
    FOR_16(N, Rest)        \
    FOR_16(16+N, Rest)

/* The above works, but has at least 1 usage caveat:

   Commas are added only by Given(), any others added - either in the
   FOR_N() macros, or in the final use, will create compiler errors.

   Its easy enough to use correctly, but compler errors are cryptic
   when you dont:
    foo.c:49: error: syntax error before ',' token
*/

struct a {
    int index;
    int i,j;
    int foo;
};

// no terminating comma here
#define COMMON_PARMS(N)  .i=(N)+1, .j=2*(N)

// try wrapping mess
#define MAKE_ARR(NAME, N, ELEM_GEN)    struct a NAME[] = { ELEM_GEN(N) }
// didnt help
// MAKE_ARR ( X, 3, (COMMON_PARMS(N), .foo=10) );
// MAKE_ARR ( X, 4, FOR_4(N, COMMON_PARMS(0), .foo=10) );

MAKE_ARR ( X, 4, FOR_4(N, COMMON_PARMS(N), .foo=10) );

struct a Y[] = {
    FOR_2(0, COMMON_PARMS(0), .foo=10)
    FOR_2(2, COMMON_PARMS(1), .foo=11)
};

int main(int c, char **v)
{
    int i;
    for (i=0; i<sizeof(X)/sizeof(struct a); i++) {
        printf("%d x:%d i:%d j:%d\n", i, X[i].index, X[i].i, X[i].j);
    }
}

/* when it runs, it does:

0 x:0 i:1 j:0
1 x:1 i:1 j:0
2 x:2 i:2 j:2
3 x:3 i:2 j:2

Things partly work:

- x is getting value of N, properly propagated thru the 2 uses of the
  FOR-2 macro

- i,j are not following N directly, their N comes from COMMON_PARMS(),
so its value is bound, when 1st expanded.


Why Cant it Work ?

I suspect what Im after cant be done, and Ill guess why - pls comment here.

- Im trying to late-bind N, in-side the For-N macros

- in lisp-ese: (forgive me)

    FOR_2(2, 'COMMON_PARMS(N), .foo=11)

- I cant use N in the X-decl, since its not a macro invocation, and N
  doesnt exist.  TRY THIS. nope

- is there something with # or ## that could force a rescan, or does 
this quote preclude it?

  6.10.3.1 Argument substitution
1 After the arguments for the invocation of a function-like macro have 
been identified,
  argument substitution takes place. A parameter in the replacement 
list, unless preceded
  by a # or ## preprocessing token or followed by a ## preprocessing 
token (see below), is
  replaced by the corresponding argument after all macros contained 
therein have been
  expanded. Before being substituted, each argument's preprocessing 
tokens are
  completely macro replaced as if they formed the rest of the 
preprocessing file; no other
  preprocessing tokens are available.


Ive run out of ideas here, any help ?

*/

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-06-08 17:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-08 17:19 C preprocessor For loops ? Jim Cromie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).