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