Подтвердить что ты не робот

Почему gcc жалуется на мои циклы?

У меня есть довольно тривиальный код, но gcc жалуется (в -O3 -march=native) на разворот цикла:

cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations]
for(auto& plan : fw)
^

Вот (лишен всего fftw, иначе это будет довольно длинная версия моего кода

class FFTWManager
{
    public:
        void setChannels(unsigned int n)
        {
            fw.resize(n);
            bw.resize(n);
                            //some fftw-specific stuff comes here
        }

        void forward()
        {
            for(auto& plan : fw)
                fftw_execute(plan);
        }

        void backward()
        {
            for(auto& plan : bw)
                fftw_execute(plan);
        }

    private:
        std::vector<fftw_plan> fw = {};
        std::vector<fftw_plan> bw = {};
};

В моем коде векторы никогда не превышают 2.


Редактирует в соответствии с комментариями: Я использую много флагов.

-pedantic -Wextra -Weffc++ -Wall -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wconversion -Wdisabled-optimization -Wformat -Wformat=1 -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winline -Winvalid-pch -Wunsafe-loop-optimizations -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstack-protector -Wstrict-aliasing=3 -Wswitch -Wswitch-default -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings

Я не вижу смысла говорить об информации о fftw_execute здесь, но если вы хотите увидеть весь код (который я слишком долго думал для сообщения SO), он здесь: https://github.com/jcelerier/watermarking/blob/master/src/libwatermark/transform/FFTWManager.h

GCC: gcc version 4.8.2 (Debian 4.8.2-10)

Я не понимаю, почему изменение из unsigned int в size_type меняет что-либо, поскольку я не получаю никакого предупреждения в моем методе setChannels (даже если я думаю, что он длинный unsigned int на моей платформе), и как только размер set, исходный тип переменной, который использовался для его установки, кажется мне совершенно неуместным.

Нет предупреждения с базовым for(int i = 0; i < bw.size(); i++) или с версией итератора for(auto i = bw.begin(); i != bw.end(); i++).

Я также пробовал с clang, который, похоже, распознал предупреждение swich, поэтому, я думаю, они также внедрили оптимизацию, и я не получаю никаких предупреждений (но гораздо быстрее компилирует время \o)

Извините за длинную обратную связь, меня не было.

4b9b3361

Ответ 1

Из руководства gcc:

-funsafe-loop-optimizations

Эта опция указывает оптимизатору цикла предположить, что индексы цикла не переполняются, и что петли с нетривиальным условием выхода не являются бесконечными. Это позволяет использовать более широкий диапазон оптимизации циклов, даже если сам оптимизатор цикла не может доказать, что эти допущения действительны. Если вы используете -Wunsafe-loop-optimizations, компилятор предупреждает вас, если он найдет этот тип цикла.

Таким образом, по-видимому, реализация цикла range-for в компиляторе как-то нарушена тем, что он вызывает это предупреждение. Вы можете либо отключить это конкретное предупреждение, либо отключить эту конкретную оптимизацию... Я бы посоветовал последнее, поскольку мне непонятно, действительно ли выполняется оптимизация или нет, когда срабатывает предупреждение.