On Wed, Aug 3, 2016 at 12:06 PM, Vikram Mulukutla
<[email protected]> wrote:
> Hi,
>
> The program listed below seems to invoke optimization behavior that produces
> different results pre 4.8 and 4.8+ versions of gcc. Using the -fno-tree-vrp
> option makes things consistent again. I make no claim of an understanding of
> what this flag really does.
>
> The program is badly written since the first operand to && in the while loop
> conditional will cause an invalid array access. I'm assuming that
> optimization behavior is unpredictable when the assumption that there will
> be no invalid array accesses is broken (and thus execution/output is
> untrustworthy), but I am curious as to why there is a change with 4.8+. The
> only concern I'd have is if this change may somehow affect other, correctly
> written code.
>
> # gcc 4.8 produces this:
> $ gcc-4.8 -O2 fk2.c && ./a.out
> i after loop (array size is 5): 5
> found at 5, answer is 0
>
> # pre gcc 4.8 produces this:
> $ gcc-4.4 -O2 fk2.c && ./a.out
> i after loop (array size is 5): 5
> This should be printed.
> found at 4, answer is 6
>
> $ gcc-4.6 -O2 fk2.c && ./a.out
> i after loop (array size is 5): 5
> This should be printed.
> found at 4, answer is 6
>
> Program:
>
> #include <stdio.h>
>
> #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
>
> unsigned int numbers[] = {
> 10,
> 9,
> 8,
> 7,
> 6,
> };
>
> /* find the element closest to elem */
> int main()
> {
> unsigned int elem = 0;
> unsigned int i = 0;
>
> while ((elem < numbers[i]) && (i < ARRAY_SIZE(numbers)))
> i++;
You are invoking undefined behavior by accessing numbers[5].
Thanks,
Andrew Pinski
>
> printf("i after loop (array size is %lu): %d\n",
> ARRAY_SIZE(numbers), i);
>
> if (i == ARRAY_SIZE(numbers)) {
> printf("This should be printed.\n");
> i--;
> }
>
> printf("found at %d, answer is %u\n", i, numbers[i]);
>
> return 0;
> }
>
> Thanks,
> Vikram