Order of Evaluation

I have a conditional branch with a lot of conditions.

else if (i == 4 &&
         ((c == '0' && (buf[3] == '1'
                     || buf[2] == '2'))
       || (c >= '1' && c <= '2')
       || (c == '3' && (buf[3] == '0'
                     || buf[2] == '2'))
      || ((c >= '4' && c <= '9') && (buf[3] == '0'
                                 || (buf[3] == '1' && buf[2] == '2'))))) {

What I am curious about is, if the microcontroller will evaluate the inner-most parenthesis first or if it will look first at "i == 4"?

C/C++ evaluates from left to right observing operator precedence and skips logical paths that can no more become true.

Yes, yes you do. Is there no other way to express whatever it is you doing there?

And seeing it's already an else thing, I be curious whether there are other tangles of logic up in there…

Just curious. :wink:

a7

Better avoided if you can - hard to understand and therefore difficult to debug.

So this is receiving a time of day in a string of ascii characters. This happens to be the HOURS ONES position, so this chacter can be 0-9, but would only be 0' in 24-hour mode or if in 12 hour mode, the HOURS TENS is '1' or '1' or '2' under any other conditions, or '3' in 24-hour mode or if HOURS ONES is '0', or '4' to '9' if HOURS TENS is '0' or in 24-hour mode AND HOURS TENS is '1'.

The rest of the string is not nearly as complicated.

"I==4" evaluates first because of the left to right rule. If i is not 4, the rest will not be evaluated at all.

Probably not. The result would be the same whether it was evaluated first or later, but it might be faster/more efficient because "I==4" does get evaluated first, because it is on the left. But in this case, not much faster because the stuff on the right is all pretty simple.

Your comment reads right from the textbook. But doesn't answer my question. As "i==4" is left of "(buf[3] == '1' && buf[2] == '2')" but the latter is several parenthesis deep, which one evaluates first? Could I insure "i==4" would evaluate first by nesting it an equal number of parenthesis deep? Do I NEED to to get it to evaluate first?

Thank you. This is what I needed to know.

As he wrote
The left side is evaluated first, so I == 4

LOL, that clears it right up!

Code to get working and never touch. I came across a comment once

/* you are not expected to understand this or remember writing it */

FWIW "short circuit" evaluation of logical expressions can save time, but more important can be used to test, then proceed or not, like

int denom;

…


if (denom != 0 && num / denom)
{
    ... // ensures that calculating num/denom never results in divide-by-zero error   
}

from the Wikipedia article on short circuit evaluation. Read it at the beach…

a7

This would only change if there was a function call in any part of the statement? The function would return it's value before the rest of the condition is evaluated?

How many wrong assumptions do you still have in mind?

nope...

Order of evaluation - cppreference.com Just trying to understand. I don't mind a complicated conditional branch as long as I don't have to dwell on evaluating it with every iteration through the loop, so if I better understand, I can order things so that the more complicated evaluation happens under specific conditions. If, for example, some part of the more right part of the condition were to slow things down, I could nest it in a seperate condition, or make my function calls before or nested, depending on how it all works out, but right now, I'm a little confused, so I'm asking questions, if that's ok.

you can build an evaluation tree for your expression, the first parts looks like this

It starts evaluating i == 4.

At the top you have a logical AND, so the compiler will know the whole thing is wrong if the left expression is wrong. if it's not false (so true), then it goes look at the next piece. since it's a logical OR, it will evaluate them left to right and stop when one is true (since true && true is true)

so if c == '0' is false, the second && will be false and thus (buf[3] == '1' || buf[2] == '2') won't even be evaluated (skip steps 3 and 4). if it's true, then it will look at buf[3] == '1' (step 3) and if it's true then the second part (step 4) does not need to be evaluated (since true OR xxx is true)

etc

Def OK, but I don't think there is a processing time issue worth the human time you might spend minimising it.

This would be a fun one to instrument and see if.

a7

That is cool. What did you use to do that? I could see that very useful if automated, to be helpful in debugging.

I just drew it with a graphic editor (keynote on my Mac - kinda like powerpoint for PC just better :wink: ) and looking at your formula

It has diminishing returns, but in this case, I only deal with the problematic HOURS ONES position when I am actually evaluating for HOURS ONES.

Haha, Imma guess you're in the more years left than lived phase of your life.…

a7