Ошибка оптимизации g ++ на osx с использованием -O3 - PullRequest
2 голосов
/ 28 ноября 2011

Следующий код выдает неправильный код завершения при компиляции с -O3.Я думаю, что внутренний цикл оптимизируется неправильно.С -O2 или -fno-inline это работает.Создать более простой пример сложно, потому что любые небольшие изменения и ошибка исчезают.

Скомпилировано с:

/usr/bin/g++ -O3 -o bugexample bugexample.cpp

Код:

#include <vector>

int test(std::vector<char>& a, int& b)
{
    std::vector<int> z;
    z.push_back(10);
    z.push_back(10);

    int d = (int)a.size();

    int x = 1;
    for (int j = 0; j < 2; j++)
    {
        int c = j - 1;

        for (int i = 0; i < d; i++) 
        {
            if (j == 0)
            {
            }
            else if (i == 0)
            {
            }
            else
            {
                if (a[j] == a[i - 1])
                {
                    b = c + 1;
                    x = 2;
                }
                z[i] = 1;
            }
        }
    }

    return x;
}


int main(int argc, char* argv[])
{
    std::vector<char> a;
    a.push_back('a');
    a.push_back('a');
    int b = 1;
    return test(a,b);
}

Версия компилятора:

/usr/bin/g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~123/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)

Заинтересован в любых инсайтах или доказательствах, что это моя вина.

Редактировать: Код выхода - 1, тогда как b 2.

1 Ответ

1 голос
/ 28 ноября 2011

Ммм, это какое-то состязание по зашифрованному коду?

Насколько я могу судить, вы пытаетесь провести какой-то тест палиндрома на входном векторе.Только

  • цикл var j имеет жестко закодированную верхнюю границу 2 (что, вероятно, также должно было быть a.size ()?)
  • вы возвращаете толькопроверка последней позиции
  • у вас были все виды избыточных условий
  • у вас были необоснованные неконстантные аргументы
  • у вас не было z vector
  • у вас было ненужное использование int для bool (1 => false - не найдено, 2 => true - найдено)
  • у вас было ненужное использование параметра out b;Я заменил этот bool тип возвращаемого значения значением b (с b == - 1, указывающим, что совпадение не найдено)

При упрощении кода для этих вещей я получаю этот код, и(как и ваш собственный код) он ведет себя одинаково для всех уровней оптимизации на g ++ 4.6.1:

#include <vector>

int test(const std::vector<char>& a)
{
    /* int j = 1; // was: for (int j = 1; j < 2; j++) */

    for (int i = a.size()-1; i > 1; i--) 
        if (a[1] == a[i - 1])
            return 1;

    return -1;
}


int main(int argc, char* argv[])
{
    std::vector<char> a(2, 'a');
    int b = test(a);

    return b==-1? 1 : 2;
}
...