For some reason having an empty while loop in a release build hangs, while having it in the debug build works fine. This example works in debug but hangs in release:
<
The reason is of course due to compilers optimizations, as already noted in the comments.
Remembering that Objective-C is built on top of C, I put together a simple C example with different levels of optimizations and here's the result.
int main(int argc, char const *argv[]) {
char _isReadyForData = 0;
while (!_isReadyForData);
return 0;
}
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%_isReadyForData = alloca i8, align 1
store i32 0, i32* %retval
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i8 0, i8* %_isReadyForData, align 1
br label %while.cond
while.cond: ; preds = %while.body, %entry
%0 = load i8* %_isReadyForData, align 1
%tobool = icmp ne i8 %0, 0
%lnot = xor i1 %tobool, true
br i1 %lnot, label %while.body, label %while.end
while.body: ; preds = %while.cond
br label %while.cond
while.end: ; preds = %while.cond
ret i32 0
}
define i32 @main(i32 %argc, i8** nocapture %argv) #0 {
entry:
br label %while.cond
while.cond: ; preds = %while.cond, %entry
br label %while.cond
}
As you can see, the compiler produces an infinite loop when optimizing, since the local variable _isReadyForData
is useless in that context and therefore is removed.
As suggested by @faffaffaff, using the volatile
keyword on _isReadyForData
may solve the issue.
define i32 @main(i32 %argc, i8** nocapture %argv) #0 {
entry:
%_isReadyForData = alloca i8, align 1
store volatile i8 0, i8* %_isReadyForData, align 1
br label %while.cond
while.cond: ; preds = %while.cond, %entry
%_isReadyForData.0.load1 = load volatile i8* %_isReadyForData, align 1
%lnot = icmp eq i8 %_isReadyForData.0.load1, 0
br i1 %lnot, label %while.cond, label %while.end
while.end: ; preds = %while.cond
ret i32 0
}
But I definitely agree with @rmaddy in saying that you'd better change the flow of your program and use driven logic, instead of patching what you have already.