[arch-general] gcc: loop do not terminate

LANGLOIS Olivier PIS -EXT olivier.pis.langlois at transport.alstom.com
Mon May 13 14:20:05 EDT 2013


I have just been hit by something:

lano1106 at hpmini ~/dev/gcc-test $ g++ --version
g++ (GCC) 4.8.0 20130502 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

lano1106 at hpmini ~/dev/gcc-test $ g++ -O2 -o test1 test1.cpp test1_init.cpp
lano1106 at hpmini ~/dev/gcc-test $ ./test1
item 0
 a: 1
lano1106 at hpmini ~/dev/gcc-test $ g++ -O1 -o test1 test1.cpp test1_init.cpp
lano1106 at hpmini ~/dev/gcc-test $ ./test1
item 0
 a: 1
lano1106 at hpmini ~/dev/gcc-test $ g++ -O0 -o test1 test1.cpp test1_init.cpp
lano1106 at hpmini ~/dev/gcc-test $ ./test1
item 0
 a: 1
item 1
 a: 2
lano1106 at hpmini ~/dev/gcc-test $ cat test1.h

struct A
{
        int a;
        int b;
        int c;
};

struct B
{
        int numelem;
        /*
         * Old C trick to define a dynamically sizable array just by allocating
         * sizeof(B) + (numelem-1)*sizeof(A) memory.
         */
        A   item[1];
};

void initArr(B *p);

lano1106 at hpmini ~/dev/gcc-test $ cat test1_init.cpp
#include "test1.h"

void initArr(B *p)
{
        p->numelem = 2;
        p->item[0].a = 1;
        p->item[1].a = 2;
}

lano1106 at hpmini ~/dev/gcc-test $ cat test1.cpp
/*
 * Author: Olivier Langlois <olivier at trillion01.com>
 *
 * Purpose: Small test to highlight gcc optimization bug
 */

#include <stdio.h>
#include <string.h>
#include "test1.h"

/*
 * Create a B array with the intent of only using the first item.
 * The 19 other items sole purpose is to create a buffer large enough
 * to accomodate A array needs.
 */
#define MAXBLEN 20

int main(int argc, char *argv[])
{
        B arr[MAXBLEN];
        memset(arr,0,sizeof(arr));

        initArr(arr);

        for( int i = 0; i < arr[0].numelem; ++i )
        {
                printf( "item %d\n"
                        " a: %d\n",
                        i,
                        arr[0].item[i].a);
        }

        return 0;
}

>From gcc website, this is not a bug:

Loops do not terminate

    This is often caused by out-of-bound array accesses or by signed integer overflow which both result in undefined behavior according to the ISO C standard. For example

        int
        SATD (int* diff, int use_hadamard)
        {
          int k, satd = 0, m[16], dd, d[16];
          ...
            for (dd=d[k=0]; k<16; dd=d[++k])
              satd += (dd < 0 ? -dd : dd);

    accesses d[16] before the loop is exited with the k<16 check. This causes the compiler to optimize away the exit test because the new value of k must be in the range [0, 15] according to ISO C.

    GCC starting with version 4.8 has a new option -fno-aggressive-loop-optimizations that may help here. If it does, then this is a clear sign that your code is not conforming to ISO C and it is not a GCC bug.

I am surprised that I didn't hit the problem before but I am seriously considering using '-fno-aggressive-loop-optimizations' in my own makepkg.conf. I just want to test others feeling on this discovery to see if it wouldn't be a good idea to make the switch standard in Arch...


________________________________
CONFIDENTIALITY : This e-mail and any attachments are confidential and may be privileged. If you are not a named recipient, please notify the sender immediately and do not disclose the contents to another person, use it for any purpose or store or copy the information in any medium.


More information about the arch-general mailing list