435,512 Members | 3,790 Online
Need help? Post your question and get tips & solutions from a community of 435,512 IT Pros & Developers. It's quick & easy.

# Nested conditional expressions ---- good idea/bad idea?

 P: n/a Below you will see an example of a nested conditional expression that this colleague of mine loves. He claims that it is more efficient that a multi-level if-else-if structure. Moreover, our complexity analyzer tool supposedly does not pick it up. Is it really more efficient? Personally I find this coding style extremely cryptic, misleading and error-prone. I believe that I have removed all traces of proprietary-ness from this coding example by multiple text substitutions. --NS /************************************************** ***********/ #include #define QWER 0x1000 #define TYUI 0x2000 #define ASDF 0x4000 #define GHJK 0x8000 #define ZXCV 0x10000 #define BNML 0x20000 void print_value(int code, int type) { printf(" ==> %s, Type %02X \n", (code == QWER ? "QWER": code == TYUI ? "TYUI": code == ASDF ? "ASDF": code == GHJK ? "GHJK": code == ZXCV ? "ZXCV": code == BNML ? "BNML": "????"), type); } main(void) { print_value(BNML, 256); print_value(ZXCV, 512); print_value(GHJK, 1024); print_value(ASDF, 768); print_value(TYUI, 128); print_value(QWER, 64); print_value(BNML|QWER, 32); } Nov 14 '05 #1
10 Replies

 P: n/a ni*************@yahoo.com wrote: Below you will see an example of a nested conditional expression that this colleague of mine loves. He claims that it is more efficient that a multi-level if-else-if structure. Moreover, our complexity analyzer tool supposedly does not pick it up. Is it really more efficient? The idea of efficiency is not a C language issue. Personally I find this coding style extremely cryptic, misleading and error-prone. it is I believe that I have removed all traces of proprietary-ness from this coding example by multiple text substitutions. --NS /************************************************** ***********/ #include #define QWER 0x1000 #define TYUI 0x2000 #define ASDF 0x4000 #define GHJK 0x8000 #define ZXCV 0x10000 #define BNML 0x20000 void print_value(int code, int type) { printf(" ==> %s, Type %02X \n", (code == QWER ? "QWER": code == TYUI ? "TYUI": code == ASDF ? "ASDF": code == GHJK ? "GHJK": code == ZXCV ? "ZXCV": code == BNML ? "BNML": "????"), type); } main(void) { print_value(BNML, 256); print_value(ZXCV, 512); print_value(GHJK, 1024); print_value(ASDF, 768); print_value(TYUI, 128); print_value(QWER, 64); print_value(BNML|QWER, 32); } Efficiency depends on things outside the scope of C (compiler, processor, etc.). I doubt there would be any meaningful efficiency gain from doing this, it might even be more inefficient (confuses compiler's optimization stages?!?). I personally would never write code like this, and I question the motives of programmers that do (showing off? making their code harder for other to understand?). [OT] If this is an embedded system with scarce resources, and you need every nanosecond of time and bit of memory, then run tests (don't guess by looking at C code- that is out of the question!!!!). Early on in the software engineering process, your company probably did a thorough study of possible "coarse" granular optimization practices that will help make efficient code for your particular implementation. Stick to this, but don't play around with little details in the C source (keep code looking clean). Near the end of your design cycle, if you find you still need more optimization (which you shouldn't if you prepared properly) then fine tune it (fine-granular optimizations). But compilers these days are quite good at doing these optimizations for you, so only "try" your tweaks if everything else fails (which it shouldn't have, if you planned properly). Also, prepare for optimizations by building proper interfaces (like making custome interfaces for everything, including data types.. imagine that coding is all done, but you realize that using int instead long for a whole section of code will increase speed by a factor of 2 without breaking the code... do you want to make a 1 line change or ... you get the picture). Nov 14 '05 #2

 P: n/a ni*************@yahoo.com wrote: Below you will see an example of a nested conditional expression that this colleague of mine loves. He claims that it is more efficient that a multi-level if-else-if structure. Moreover, our complexity analyzer tool supposedly does not pick it up. Is it really more efficient? Personally I find this coding style extremely cryptic, misleading and error-prone. I believe that I have removed all traces of proprietary-ness from this coding example by multiple text substitutions. .... snip ... After putting some decent indentation in (see sig below) you have: printf(" ==> %s, Type %02X \n", (code == QWER ? "QWER": code == TYUI ? "TYUI": code == ASDF ? "ASDF": code == GHJK ? "GHJK": code == ZXCV ? "ZXCV": code == BNML ? "BNML": "????"), type); The other choice here is a temporary, and an if else chain: char *tmp; if (code == QWER) tmp = "QWER"; else if (code == TYUI) tmp = "TYUI"; else if (code == ASDF) tmp = "ASDF"; else if (code == GHJK) tmp = "GHJK"; else if (code == ZXCV) tmp = "ZXCV"; else if (code == BNML) tmp = "BNML"; else tmp = "????"; printf(" ==> %s, Type %02X \n", tmp, type); Now, which is cleaner and more readable? Ignoring efficiency, I think your colleague is doing just fine in this case. There are few places where I would use the ? operator, yet this is one of them. I would, however, probably isolate it in a routine such as: char *typetostring(enum type t); which would allow printf(" ==> %s, Type %02X \n", typetostring(code), type); You still have the temporary, it is just effected by the function return value. However you can reuse the translation routine if needed elsewhere. -- "If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers." - Keith Thompson Nov 14 '05 #3

 P: n/a CBFalconer wrote: ni*************@yahoo.com wrote: Below you will see an example of a nested conditional expression that this colleague of mine loves. He claims that it is more efficient that a multi-level if-else-if structure. Moreover, our complexity analyzer tool supposedly does not pick it up. Is it really more efficient? Personally I find this coding style extremely cryptic, misleading and error-prone. I believe that I have removed all traces of proprietary-ness from this coding example by multiple text substitutions. ... snip ... After putting some decent indentation in (see sig below) you have: printf(" ==> %s, Type %02X \n", (code == QWER ? "QWER": code == TYUI ? "TYUI": code == ASDF ? "ASDF": code == GHJK ? "GHJK": code == ZXCV ? "ZXCV": code == BNML ? "BNML": "????"), type); The other choice here is a temporary, and an if else chain: char *tmp; if (code == QWER) tmp = "QWER"; else if (code == TYUI) tmp = "TYUI"; else if (code == ASDF) tmp = "ASDF"; else if (code == GHJK) tmp = "GHJK"; else if (code == ZXCV) tmp = "ZXCV"; else if (code == BNML) tmp = "BNML"; else tmp = "????"; printf(" ==> %s, Type %02X \n", tmp, type); Now, which is cleaner and more readable? Ignoring efficiency, I think your colleague is doing just fine in this case. There are few places where I would use the ? operator, yet this is one of them. I would, however, probably isolate it in a routine such as: I personally would never nest ternary : ? opeartors like this (especially never putting the whole thing inside a printf argument!). If statements are less error prone and in this case, there really is no reason to use :? operators (count the difference in number of lines???). Nov 14 '05 #4

 P: n/a Luke Wu wrote: I personally would never nest ternary : ? opeartors like this (especially never putting the whole thing inside a printf argument!). If statements are less error prone and in this case, there really is no reason to use :? operators (count the difference in number of lines???). State your preference: hand_type = is_straight ? is_flush ? STRAIGHT_FLUSH : STRAIGHT : is_flush ? FLUSH : NOTHING; vs. if (is_straight) { if (is_flush) { hand_type = STRAIGHT_FLUSH; } else { hand_type = STRAIGHT; } } else { if (is_flush) { hand_type = FLUSH; } else { hand_type = NOTHING; } } Neither is "righter" or "wronger" than the other, and both clarity and beauty lie in the eye of the beholder. Still, to my eye the first is preferable. -- Er*********@sun.com Nov 14 '05 #5

 P: n/a On 1/31/05 10:20 AM, in article ct**********@news1brm.Central.Sun.COM, "Eric Sosman" wrote: Luke Wu wrote: I personally would never nest ternary : ? opeartors like this (especially never putting the whole thing inside a printf argument!). If statements are less error prone and in this case, there really is no reason to use :? operators (count the difference in number of lines???). State your preference: hand_type = is_straight ? is_flush ? STRAIGHT_FLUSH : STRAIGHT : is_flush ? FLUSH : NOTHING; vs. if (is_straight) { if (is_flush) { hand_type = STRAIGHT_FLUSH; } else { hand_type = STRAIGHT; } } else { if (is_flush) { hand_type = FLUSH; } else { hand_type = NOTHING; } } Neither is "righter" or "wronger" than the other, and both clarity and beauty lie in the eye of the beholder. Still, to my eye the first is preferable. Debugging is much easier in the latter. Try to set a breakpoint on the ternary version. Nov 14 '05 #6

 P: n/a Gregory Dean wrote: On 1/31/05 10:20 AM, in article ct**********@news1brm.Central.Sun.COM, "Eric Sosman" wrote:Luke Wu wrote:I personally would never nest ternary : ? opeartors like this(especially never putting the whole thing inside a printf argument!).If statements are less error prone and in this case, there really is noreason to use :? operators (count the difference in number oflines???). State your preference:hand_type = is_straight ? is_flush ? STRAIGHT_FLUSH : STRAIGHT : is_flush ? FLUSH : NOTHING;vs.if (is_straight) { if (is_flush) { hand_type = STRAIGHT_FLUSH; } else { hand_type = STRAIGHT; }}else { if (is_flush) { hand_type = FLUSH; } else { hand_type = NOTHING; }}Neither is "righter" or "wronger" than the other, andboth clarity and beauty lie in the eye of the beholder.Still, to my eye the first is preferable. Debugging is much easier in the latter. Try to set a breakpoint on the ternary version. (1) No problem, if you'll let me choose a debugger that can set breakpoints at arbitrary machine instructions. (2) Try to set a breakpoint in the latter form, after an optimizing compiler has transmogrified the code and generated the same instructions as for the former form. (3) Debugging is inferior to inspection, in the sense that a debugger can (at best) show you things that have actually happened, while inspection can drive assertions about all the things that can and cannot happen. I feel that the former is easier to inspect than the latter, hence easier to prove things about, hence less likely have bugs in the first place! (4) Debuggers are like crutches: When you need them you do in fact need them, but you will never progress as well as when you can do without them. (5) -- no, I'm starting to rant. Again ... -- Er*********@sun.com Nov 14 '05 #7

 P: n/a ni*************@yahoo.com wrote: Below you will see an example of a nested conditional expression that this colleague of mine loves. He claims that it is more efficient that a multi-level if-else-if structure. Make him show you the profiling data he gathered that allowed him to reach this conclusion. Terse code doesn't necessarily equate to fast or efficient code. In fact, I can think of cases the opposite is true; unrolling a loop results in more verbosity, but can improve perfomance. OTOH, a terse recursive algorithm can incur significant overhead compared to a more verbose, iterative equivalent (fibonacci or factorials, for example). Having said that, it's possible that nested ternary expressions are faster/smaller than an equivalent if-else structure, but you'd have to profile the two versions to know for sure. Nov 14 '05 #10

### This discussion thread is closed

Replies have been disabled for this discussion.