This piece of code has a bug in the loop termination condition. However, I still don't understand the compiler's decision - it seems to be getting into the loop one more time.
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
#define ARR_SIZE 25
int a[ARR_SIZE];
memset (a,1,sizeof(a)); /*filling the array with non-zeros*/
int i = 0;
for (i=0; (a[i] != 0 && i < ARR_SIZE); i++)
{
printf ("i=%d a[i]=%d\n",i,a[i]);
}
return 0;
}
When compiling this with -O2
or -O3
the loop is not terminated when expected - it prints also a line for when i == ARR_SIZE
.
> gcc -O3 test_loop.c
> ./a.out
i=0 a[i]=16843009
i=1 a[i]=16843009
...
i=23 a[i]=16843009
i=24 a[i]=16843009
i=25 a[i]=32766 <=== Don't understand this one.
> gcc -O0 test_loop.c
> a.out
i=0 a[i]=16843009
i=1 a[i]=16843009
...
i=23 a[i]=16843009
i=24 a[i]=16843009
>
The gcc version is this: gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
I don't see this happening on gcc 4.4.7-18
.
Also other sizes of ARR_SIZE
doesn't give the same results.
When i == ARR_SIZE
your condition will evaluate a[i]
invoking UB
for (i=0; (a[i] != 0 && i < ARR_SIZE); i++)
// ^^^^ Undefined Behaviour
{
printf ("i=%d a[i]=%d\n",i,a[i]);
}
Swap the conditions: for (... (i < ARR_SIZE && a[i] != 0) ...)
to take advantage of "short-circuit boolean evaluation".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With