Sujet : Re: Concatenated if and preprocessor
De : Keith.S.Thompson+u (at) *nospam* gmail.com (Keith Thompson)
Groupes : comp.lang.cDate : 14. Mar 2025, 19:10:50
Autres entêtes
Organisation : None to speak of
Message-ID : <87ikobjxed.fsf@nosuchdomain.example.com>
References : 1 2
User-Agent : Gnus/5.13 (Gnus v5.13)
pozz <
pozzugno@gmail.com> writes:
Il 13/03/2025 16:44, pozz ha scritto:
Consider this code:
if (cond1) {
...
} else if (cond2) {
...
} else if (cond3) {
...
}
I want to activate every single if with a macro preprocessor. All
the combinations are possible: only the first, only the second, only
the third, the first and second... and so on.
What's the best method to have a clean code that is always compiled
without errors?
>
You're right, a real example is better to define my problem.
>
I have a project that can be compiled in different ways, depending on
the final product model (it's an embedded platform, it's a material
device).
I have three models with different characteristics: MODEL_A, MODEL_B,
MODEL_C. Three different builds that are managed at compile time by
defining MODEL macro as MODEL_A, MODEL_B or MODEL_C.
>
For each model, I could have a different features set. FEATURE_1,
FUTURE_2, FUTURE_3, ...
>
#if MODEL == MODEL_A
# define FEATURE_1 1
# define FEATURE_2 0
# define FEATURE_3 0
#elif MODEL == MODEL_B
# define FEATURE_1 0
# define FEATURE_2 1
# define FEATURE_3 0
#elif MODEL == MODEL_C
# define FEATURE_1 1
# define FEATURE_2 1
# define FEATURE_3 1
#endif
>
Now, on the full-featured model (MODEL_C) I could write:
>
if (key == 1) {
...
} else if (key == 2) {
...
} else if (key == 3) {
...
} else {
...
}
>
However, for MODEL_A I should have:
>
if (key == 1) {
...
} else {
...
}
>
For MODEL_B I should have:
>
if (key == 2) {
...
} else {
...
}
>
This is the scenario.
I thought using if(0) or if(1), but many times I receive some warnings
from the compiler (condition is always true or condition is always
false).
This indicates something that wasn't expressed in your original post:
that only one of the three runtime conditions can be true. You might
need to add a dummy "if (0)" at the top of the if/else chain if two
or more of the conditions might be true and the order is significant,
but with the new (pseudo-?)code you've posted that's not necessary.
I'll also note that you've #define'd FEATURE_1 et al as 0 or 1.
I suggest it would be more idiomatic for the FEATURE macros to be
either #define'd or #undef'ed. (I'm assuming that a feature is
either enabled or disabled, and that there aren't multiple ways
for it to be enabled.)
One way to write it is:
#ifdef FEATURE_1
if (key == 1) {
...
}
#endif
#ifdef FEATURE_2
if (key == 2) {
...
}
#endif
#ifdef FEATURE_3
if (key == 3) {
...
}
#endif
Even if FEATURE_* are all defined, only one of the "..."s will be
executed.
The second and third tests might be redundant if the first
succeeds, but that's trivial and IMHO not worth making the code
more complicated.
Or, assuming it really is a test for the value of an integer "key":
switch (key) {
#ifdef FEATURE_1
case 1:
...
break;
#endif
#ifdef FEATURE_2
case 2:
...
break;
#endif
#ifdef FEATURE_2
case 2:
...
break;
#endif
}
I'm making some assumptions based on your pseudo-code. Perhaps in
your real code, the first and second runtime conditions might
both be true and then you want to execute just the first block.
And maybe the logic will need to be changed later.
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */