C - Logical And operands are not replaceable in this case?

I am studying linked lists in C, and I came across an error that I don't understand. In the code snippet that I inserted below, when I have (a && b), I get an infinite loop, but when I run while (b && a), the program works. I am new to C and don't understand why I get an infinite loop in the first case.

This gives me an infinite loop:

while((*searchNodePtr).data != dataValue && searchNodePtr != NULL) { prevNodePtr = searchNodePtr; searchNodePtr = (*searchNodePtr).next; } 

But this works (replaced by condition operands):

 while(searchNodePtr != NULL && (*searchNodePtr).data != dataValue) { prevNodePtr = searchNodePtr; searchNodePtr = (*searchNodePtr).next; } 

Any clarifications would be greatly appreciated. Thanks.

+4
source share
2 answers

This is due to short circuit rating . In the first while you look for the NULL -pointer (undefined) behavior when searchNodePtr is NULL , because checking for NULL only happens after that.

While in the second while , when the first operand && is false, the second does not receive an estimate. Therefore, when searchNodePtr is NULL , the expression (*searchNodePtr).data not evaluated and you are not casting a NULL -pointer.

+6
source

C uses short circuit calculations in logical expressions (operator && , operator || , etc.).

In the expression a && b value of b will be evaluated only if a true (nonzero). This is because if a is false (zero), then the value of b will not result in the expression a && b .

For your specific case, (*searchNodePtr).data is a valid expression if searchNodePtr points to a valid object (and is not NULL ). Otherwise, it gives undefined behavior.

So, your first case assumes that searchNodePtr is non-NULL, dereferencing it (giving undefined behavior, which means that all bids are disabled if searchNodePtr is actually NULL), and THEN testing if searchNodePtr is NULL.

The second case checks that searchNodePtr not NULL, and then evaluates (*searchNodePtr).data and tests to see if it is true (nonzero). This is the right way to do such things.

By the way, (*searchNodePtr).data more readily expressed as searchNodePtr->data . But you still have to check if searchNodePtr not NULL.

+2
source

All Articles