macro expansion to achieve induction.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 






Im looking for a way to initialize an array of structs, ala:

  static struct sensor_device_attribute sda_fan_input[] = {
  __SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0),
  __SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1),
  __SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2),
  };
but to do so more readably / compactly, and w/o fixed N-length

since macro language doesnt have foreach loops, I tried to do induction,
(f(N) -> F(1), f(N-1)) to replace the missing loop, but Im not expanding
the 2nd iteration. (as info gcc discusses)



struct cell {
 char* name;
 int id;
};

#define CELL_INIT_1(N)         { "fan" # N "_input", N }
#define CELL_INIT_N(N)         CELL_INIT_1(N), CELL_INIT_N(N-1)
#define CELL_INIT_all(N)       CELL_INIT_N(N,1)

struct cell culture[] = {
 CELL_INIT_N(3),
 { "name", 1 }
};


the above fails as folllows:
$ make macroN
cc -g    macroN.c   -o macroN
macroN.c:75: error: initializer element is not constant
macroN.c:75: error: (near initialization for `culture[1].name')
macroN.c:75: error: initializer element is not constant
macroN.c:75: error: (near initialization for `culture[1]')

the real reason is evident in -cc -E expansion:

# 71 "macroN.c"
struct cell culture[] = {
 { "fan" "3" "_input", 3 }, CELL_INIT_N(3 -1)
};

as you can see, the recursive expansion isnt happening.

I know the above is over-simplified;  the induction doesnt
currently terminate at N=0, and this would infact result in
infinite expansion.

OTGH,

info cpp, macro pitfalls, Self-Reference Macros, says :

If the self-reference were considered a use of the macro, it
would produce an infinitely large expansion.  To prevent this, the
self-reference is not considered a macro call.  It is passed into the
preprocessor output unchanged.

SO: ie Qs

Is there any way to:
a.  induce gcc/cpp to evaluate the macro as a macro,
   perhaps a builtin _enable_recursive_eval_ modifier thigny
b.  include conditionals in the macro def
this conditional-def could serve as the hint to induce re-eval as a macro.
c.  its not clear how do this safely
the condition may not properly terminate the expansion. (want a limiter, settable ideally)
d.  an explicit 1..N loop sounds safer.

Or is there an existing way that Ive missed ?  (I hope)

tia
Jim Cromie

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux