I read a question on SO about some code that caused a runtime error, i.e. seg fault.
I tried to debug the code using ideone.com and got a strange result.
I have stripped down the code to a minimal version to reproduce the strange behavior. Therefore the code doesn't do anything meaningful. The purpose of the code is only to show the strange behavior.
Code example 1:
#include <stdio.h>
int main() {
int a[3] = {3, 2, 5};
int s[3] = {0, 0, 0};
int r = 0;
int i;
for(i = 1; i < 3; i++) {
while((a[i] < a[s[r]]) && (r >= 0))
{
r--;
}
printf("initialize s[%d] to %d\n", r+1, i);
++r;
s[r] = i;
}
printf("%d\n", r);
return 0;
}
This code gives runtime error.
See https://ideone.com/IWo6TS#stdin
So I made this minor change to the code.
Code example 2:
#include <stdio.h>
int main() {
int a[3] = {3, 2, 5};
int s[3] = {0, 0, 0};
int r = 0;
int i;
for(i = 1; i < 3; i++) {
int t = s[r]; // These 2 lines
while((a[i] < a[t]) && (r >= 0)) //
// while((a[i] < a[s[r]]) && (r >= 0)) // instead of this line
{
r--;
}
printf("initialize s[%d] to %d\n", r+1, i);
++r;
s[r] = i;
}
printf("%d\n", r);
return 0;
}
Now the code runs fine and produces the output:
initialize s[0] to 1
initialize s[1] to 2
1
See https://ideone.com/qt43DL#stdin
The compiler used is GCC 6.3.
The difference is only:
.... a[s[r]] .... in example 1
and
int t = s[r]; in example 2
.... a[t] ....
So the question is why does the first example fail and the second execute fine?
I have looked for UB in the code but could not spot any. Is there UB in the code?
Is this a (known) bug in GCC 6.3?
UPDATE
As correctly pointed out by Scott Hunter the two code examples are not doing the same.
The first example fails due to UB because the variable r changes to -1 inside the body of the while and in the next condition check of the while it accesses s[-1]. So UB for example 1.