• AVR Freaks

AnsweredHot!How are multiple if conditions tested?

Page: 12 > Showing page 1 of 2
Author
Thorben.Z
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2017/06/03 06:33:33
  • Location: 0
  • Status: offline
2020/09/12 03:01:25 (permalink)
0

How are multiple if conditions tested?

So I'm programming something on a fairly slow pic and was just wondering how the compiler generates different if-condition checks.
 
When using something like 
if(startChannel < channel && channel < startChannel + 5)

does the compiler generate this
lw $t0, startChannel
lw $t1, channel
slt $s0, $t1, $t0
bne $s0, $zero, skip
   nop
addi $t0, $t0, 4
slt $s0, $t0, $1
bne $s0, $zero, skip
   nop
/*Do stuff*/
skip:
/*continue program*/

Or does it do this
lw $t0, startChannel
lw $t1, channel
slt $s0, $t1, $t0
addi $t0, $t0, 4
slt $s1, $t0, $1
or $t0, $s0, $s1
bne $t0, $zero, skip
   nop
/*Do stuff*/
skip:
/*continue program*/

I know it won't make a large difference here (if any), but I wanted a fairly simple example ;)
Also I have only worked with asm on mips32 so excuse any wrong instructions
#1
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/12 04:08:26 (permalink) ☼ Best Answerby Thorben.Z 2020/09/12 16:00:41
+2 (2)
Thorben.Z
So I'm programming something on a fairly slow pic and was just wondering how the compiler generates different if-condition checks.
 
When using something like 
if(startChannel < channel && channel < startChannel + 5)


The && operator has a left-to-right order of evaluation; i.e. if the first comparison equals to 0, the second comparison is not evaluated.
 
Edit: That is equivalent to this:
if (startChannel < channel) {
  if (channel < startChannel + 5) {
    // ...
  }
}

 
post edited by 1and0 - 2020/09/12 04:17:45
#2
Thorben.Z
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2017/06/03 06:33:33
  • Location: 0
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/12 16:01:33 (permalink)
+1 (1)
if the first comparison equals to 0, the second comparison is not evaluated.

 
Ok that was exactly the thing I was looking for, thank you :)
#3
ric
Super Member
  • Total Posts : 29543
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How are multiple if conditions tested? 2020/09/13 01:45:00 (permalink)
+2 (2)
Agree, some more parenthesis could make it clearer.
If you are intimately familiar with the C precedence rules, it may be obvious what it will do, but it is easy to confuse them and get tripped up by the precedence NOT doing what you wanted.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
dan1138
Super Member
  • Total Posts : 4184
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/13 12:07:06 (permalink)
+1 (1)
The C language syntax rules for the binding precedence of logical, relational, and assignment operators have a long history of discussion (you know flame wars) on the internet. It would be typical for this thread to get trolled into another "discussion" on the use of parentheses versus syntax rules, I for one, would not be amused.
 
vexorg and ric suggestions to use parentheses to clearly show how you want the expression evaluated is a good one.
 
Think of it as a note to the you in the future that has gone looking for bugs and wonder what was the idiot thinking that wrote this code. So be kind an throw your future self a bone. You will thank yourself later, i know I have.
#5
crosland
Super Member
  • Total Posts : 2145
  • Reward points : 0
  • Joined: 2005/05/10 10:55:05
  • Location: Warks, UK
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/14 13:47:43 (permalink)
0
vexorg
 The +5 and the second < have a higher precedence than &&. So the && should be evaluated last, does that mean:
 
(startChannel < channel && channel < startChannel + 5)
 
is evaluated differently to:
 
( (startChannel < channel)  &&  (channel < (startChannel + 5)) )

 
To determine whether it's ((channel < startChannel) + 5) or (channel < (startChannel + 5)) you also need to consider the relative precedence of + and <. Google is your friend.
 
 
#6
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 12032
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/14 14:16:25 (permalink)
+3 (3)
Keep in mind this has nothing to do specifically with XC8; this is all dictated by the C standard.
#7
ric
Super Member
  • Total Posts : 29543
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How are multiple if conditions tested? 2020/09/14 16:02:22 (permalink)
+2 (2)
And don't forget, when you have to choose between "what would make sense", and "what is dictated by the C standard", the two don't always agree, and in every case it is "what is dictated by the C standard" that prevails.

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#8
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/14 19:30:44 (permalink)
0
The precedence of the operators used in OP's expression is easily memorized. In order of higher to lower precedence:

The four basic arithmetic operators:

  *  /
  +  -

The relational operators:

  <  <=  >  >=

The equality operators:

  ==  !=

The logical AND operator (think of it as a multiplication):

  &&

The logical OR operator (think of it as an addition):

  ||

That being said, I would write it as:
if ( (startChannel < channel) && (channel < startChannel + 5) )

#9
ric
Super Member
  • Total Posts : 29543
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How are multiple if conditions tested? 2020/09/15 02:03:54 (permalink)
+2 (2)
vexorg
My point was that your code example in post 3 doesn't follow precedence, since you wont evaluate the +5 or second >.
Meaning the startChannel+5 should be first, then the two < conditions, and lastly the &&.

Um no.
You seem very confused about precedence.
His example was precisely correct.
If the expression before the "&&" evaluates to "false", then the expression after the "&&" is never evaluated.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#10
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 03:08:49 (permalink)
+1 (1)
vexorg
Not confused at all precedence defines the order of operation in an equation, it appears C is short cutting the process, rightly or wrongly. But by the rules the second part should be evaluated first since the +5 is highest.

There is precedence and then there is sequence point.

Take OP's if() expression as an example, the && operator guarantees left-to-right evaluation. There is a sequence point after the evaluation of the first operand (startChannel < channel). If the first operand compares equal to 0, the second operand (channel < startChannel + 5) is NOT evaluated. There is no point to evaluate the second operand when the condition is already known as 0 (false). That IS the C Standard!


#11
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 04:58:15 (permalink)
0
To clarify further, the left-to-right evaluation means the order of evaluation is specified to perform the first operand (subexpression) on the left before the second operand on the right.
 
#12
NorthGuy
Super Member
  • Total Posts : 6486
  • Reward points : 0
  • Joined: 2014/02/23 14:23:23
  • Location: Northern Canada
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 06:56:16 (permalink)
+1 (1)
vexorg
Not confused at all precedence defines the order of operation in an equation, it appears C is short cutting the process, rightly or wrongly. But by the rules the second part should be evaluated first since the +5 is highest.



You can look at the precedence as the method to put parentheses if they're missing. Such as, if the compiler sees:
 
a*b+c

 
if calculates
 
(a*b)+c

 
as opposed to
 
a*(b+c)

 
because multiplication has higher precedence than addition.
 
If the precedence is the same, then direction is used. Say,
 
a-b+c

 
is evaluated left to right, as
 
(a-b)+c

 
as opposed to
 
a-(b+c)

 
Then there's an order in which the calculations are performed. Even if you set all the parentheses, the compiler still can calculate things in different order - left side first, or the right side first. Typically, this doesn't matter for the end result, but if there are side effects, which can be evaluated in any order, the things may get unpredictable, such as
 
a++ + (++a)

 
or
 
one()+two()

 
Some of the operands impose a sequence point, which mandate the order of evaluation of the sides and requires that all the side effects are completed. && is one of them. It mandates that the left side is evaluated first. It also mandates that the right side is evaluated only if the left side yields 1. This makes the following fully predictable.
 
a++ && ++a

 
The sequence points let you write handy things, such as:
 
do()||die(); // evaluates the function and dies if it returns 0.
 
selector?do():die(); // calls one of the two functions, but never both.

#13
crosland
Super Member
  • Total Posts : 2145
  • Reward points : 0
  • Joined: 2005/05/10 10:55:05
  • Location: Warks, UK
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 07:44:03 (permalink)
+1 (1)
vexorg
1and0
To clarify further, the left-to-right evaluation means the order of evaluation is specified to perform the first operand (subexpression) on the left before the second operand on the right.
 

Meaning that C uses a hybrid rather than pure precedence to work it out. Otherwise startChannel+5 would always be calculated first in the example above.


Do you know a language that would do that?
#14
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 07:45:09 (permalink)
+2 (2)
vexorg
 
Meaning that C uses a hybrid rather than pure precedence to work it out. Otherwise startChannel+5 would always be calculated first in the example above.

It has to do with sequence point. An expression is a sequence of operators and operands that specifies computation, or that generates side effects, or that performs both. The order of evaluation of subexpressions and the order in which side effects take place are both unspecified, except for a few operators which include &&, ||, ?:, and the comma operators. Read NorthGuy's post again.
 
When you think about it, for the && operation it takes only one operand of 0 to make the condition false; so it will be pointless and waste of time to compute both operands. C mandates the left-to-right order, which makes thing predictable.
 
 
#15
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 12032
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 12:50:37 (permalink)
+2 (2)
And it's obvious why it does it, the simple processor can only do one operation.comparison at time

 
It has nothing to do with the processor.  It's dictated by the C standard.  Every C compiler from every vendor does this.  The reason the C standard does it is that it would be pointless to evaluate an expression that doesn't affect the outcome of the "if" statement.
#16
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 16:26:03 (permalink)
+2 (2)
vexorg
And it's obvious why it does it, the simple processor can only do one operation.comparison at time,

As Jtemples has said, it has nothing to do with the processor. The C compilers for your multi-core processor do the same thing! It is dictated by the C Standard.

Doing it the C Standard way on a PIC16, this
        movf    channel,w
        subwf   startChannel,w
        skpnc
        goto    endif
        
        movf    startChannel,w
        addlw   5
        subwf   channel,w
        skpnc
        goto    endif
        
        ; body of if()
endif:

takes 5 cycles if the first expression is false, 10 cycles if both expressions are false, and 9 cycles if both expressions are true.

Doing it YOUR way on the same PIC16, this
        movf    startChannel,w
        addlw   5
        subwf   channel,w
        movlw   1
        skpnc
        movlw   0
        movwf   result2
        
        movf    channel,w
        subwf   startChannel,w
        movlw   1
        skpnc
        movlw   0
        
        andwf   result2,w
        skpnz
        goto    endif
        
        ; body of if()
endif:

takes 16 cycles if both either expression is false and 15 cycles if both expressions are true. In addition, this way requires an additional data memory space and more program memory space.

So, it's a no-brainer which way is better and more efficient.
 
Edit: OP posted similar code in mips32 with same conclusion.
 
 
post edited by 1and0 - 2020/09/15 20:47:53
#17
NorthGuy
Super Member
  • Total Posts : 6486
  • Reward points : 0
  • Joined: 2014/02/23 14:23:23
  • Location: Northern Canada
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 18:13:06 (permalink)
+1 (1)
vexorg
Just seems odd people bark 'precedence' when it's really precedence spliced with procedural left to right, when the rules of precedence are clear in a mathematical form.



These are two different processes.
 
One process is building the expression tree. The compiler parses the text and builds the tree (not necessarily a tree, could be RPL, or any other disambiguated presentation).  Any expression consists of an operation and a number of operands. For example, if you write
 
a = b*c + d;

 
This is an expression. The operation is "=" - assignment. The first operand is "a". The second operand is an expression by itself (sub-expression if you will). The sub-expression has the operation ("+"), the first operand (b*c. which is yet another expression), and the second operand ("d"). During this process, the compiler uses precedence rules to build the expression tree correctly. Once the tree is built, the precedence rules are forgotten and not used any more.
 
The second process is generating the machine code from the expression tree, which is done by evaluating expressions starting from the root of the trees. During this process, the compiler uses ordering and sequencing rules. For example, with the above example, the root expression is "=". The compiler generates the code which does three things:
 
- finds "a"
- evaluates the second operand
- stores the result into "a"
 
The first two things are not ordered - may be done in any order.
 
The second operation is also an expression and its evaluation follows the same pattern:
 
- evaluate first operand - a*b
- evaluate second operand - c
- perform the operation (sum them up).
 
Again, the first two things may be done in any order.
 
Compiler continues this way, until everything is evaluated. Then it moves to the next statement.
 
You mixed these two different processes in your mind, and you want to dismiss the ordering rules and use precedence in both cases. Hence the confusion.
 
#18
1and0
Access is Denied
  • Total Posts : 11808
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/15 18:22:59 (permalink)
+1 (1)
Actually, doing it strictly YOUR way is even worse.
        movf    startChannel,w
        addlw   5               ; +
        movwf   result2
        
        movf    channel,w
        subwf   startChannel,w
        movlw   1
        skpnc
        movlw   0
        movwf   result1         ; first <
        
        movf    result2,w
        subwf   channel,w
        movlw   1
        skpnc
        movlw   0               ; second <
        
        andwf   result1,w       ; &&
        skpnz
        goto    endif
        
        ; body of if()
endif:

It takes 18 cycles if both either expression is false and 17 cycles if both expressions are true. It requires two additional data memory space and even more program memory space.


post edited by 1and0 - 2020/09/15 20:49:39
#19
moser
Super Member
  • Total Posts : 608
  • Reward points : 0
  • Joined: 2015/06/16 02:53:47
  • Location: Germany
  • Status: offline
Re: How are multiple if conditions tested? 2020/09/16 00:33:13 (permalink)
+2 (2)
I would like to add: The behavior of &&, || and ?: is called "Short-circuit evaluation". If one or some arguments are are sufficient to determine the result, you don't need to evaluate the remaining argument(s).
 
https://en.wikipedia.org/wiki/Short-circuit_evaluation
 
 
Btw: According the article for Fortan the language specification allows the compiler to select the method for optimization. It might be "Short-circuit evaluation" or not.
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2021 APG vNext Commercial Version 4.5