Note-to-self: short circuiting==buggy programs

Programming, for all ages and all languages.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Note-to-self: short circuiting==buggy programs

Post by earlz »

Ok, well, recently I learned in my Java programming class about short circuiting.. like
if(foo() && bar()) if foo is false, then bar will never be executed because the condition is automatically false.

Well, I wondered if C did this by default or different optimization levels and such..
GCC did this by default no matter what the optimization level, as did PCC(bsd C compiler).

Now, I'm just giving everyone a warning as to this behavior. I am almost for sure somewhere in my old code of millions of bugs, I was unaware of this.

This will probably not usually be a problem, as I can't even think of a decent example of a bug made by this.
but here is my shot at it..

Code: Select all

//shutdown code
//functions return 1 on error.
if(shutdown_terminals() || sync_disks()){
kprintf("An error occured shutting down, attempting to continue\n");
}
//....
in this example, if say some terminal got locked and could not be shutdown or something, it would return an error. This would mean the compiler would short-circuit it. So shutdown_terminals would be executed and it would return 1. This would make the OR condition TRUE. So to the compiler, there is no need to try to sync disks because the condition is already true.


Just saying all this to maybe aid someone out there trying to find a hard bug.
User avatar
stephenj
Member
Member
Posts: 140
Joined: Wed Jul 23, 2008 1:37 am
Location: Canada

Re: Note-to-self: short circuiting==buggy programs

Post by stephenj »

If you haven't already, you may want to read the K&R C book. There are a few things like this you may want to know.

Also, short-circuiting can be used to prevent errors (short circuiting != buggy programs) without writing a lot of code. Take a look at this (simple) example:

Code: Select all

while (NULL != x && 'a' != x->val) {
	x = x->next;
}
Consider the alternative without short-circuiting. We'd have to do the NULL test before the loop, and then just before it iterates. If you don't do the NULL test, then iff NULL == x, you should segfault asking for x->val.

In any event, misusing any tool may cause problems. This shouldn't really surprise anyone.

(BTW, if you look at my test expression within the while loop, you may notice that I put the constant before the variable. This prevents the annoying x = NULL issue when you meant x == NULL.)
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Note-to-self: short circuiting==buggy programs

Post by earlz »

hmm... I guess that bit is pretty nifty... maybe there should be a way to toggle short circuiting :P lol
User avatar
stephenj
Member
Member
Posts: 140
Joined: Wed Jul 23, 2008 1:37 am
Location: Canada

Re: Note-to-self: short circuiting==buggy programs

Post by stephenj »

There is, you use | instead of ||, and & instead of &&.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Note-to-self: short circuiting==buggy programs

Post by earlz »

hmm... wasn't aware of that... thanks
iammisc
Member
Member
Posts: 269
Joined: Thu Nov 09, 2006 6:23 pm

Re: Note-to-self: short circuiting==buggy programs

Post by iammisc »

Java got the idea of "short-circuiting" from C.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Note-to-self: short circuiting==buggy programs

Post by Solar »

Short-circuiting shouldn't come as a surprise; it's part of the language, every text I've seen so far on && and || mentions this, and as stevenj pointed out, it is used in many "standard" constructs (precondition checking).
Every good solution is obvious once you've found it.
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Re: Note-to-self: short circuiting==buggy programs

Post by B.E »

One of the advantages of short circuiting is this if you want to stop processing after an error and you have a few functions to call. It becomes easy to do.

For example, without short circuiting:

Code: Select all

if (!b=function1(a){
   printf("Failed to preform operation");
}else if (!c=function2(b){
   printf("Failed to preform operation");
}else if (!function3(c){
   printf("Failed to preform operation");
}
...
Would become:

Code: Select all

if (!(b=function1(a) && c=function2(b) && function3(c)))
   printf("Failed to preform operation");
Another example:

Code: Select all

if (hasNext(b) && n = Next(B)){
 // do something
} else{
 // has no next 
}
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
Post Reply