Deutsch English Français Italiano |
<87ikobjxed.fsf@nosuchdomain.example.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Keith Thompson <Keith.S.Thompson+u@gmail.com> Newsgroups: comp.lang.c Subject: Re: Concatenated if and preprocessor Date: Fri, 14 Mar 2025 11:10:50 -0700 Organization: None to speak of Lines: 141 Message-ID: <87ikobjxed.fsf@nosuchdomain.example.com> References: <vquuhg$34o8d$2@dont-email.me> <vr15ti$rtjs$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Fri, 14 Mar 2025 19:10:54 +0100 (CET) Injection-Info: dont-email.me; posting-host="bbf3b2da6e551caad2cd296cab2812d3"; logging-data="1849708"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19DI93t2kIPasOzXG3THcty" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:W1bw3bkE621uLq+wXZActvfMSeo= sha1:jY/dLgg5jTSAIHG0nFk7ATXrMTs= 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.com void Void(void) { Void(); } /* The recursive call of the void */