c++ - rulos - rizos definidos
¿Por qué gcc se queja de mis bucles? (1)
Tengo un código bastante trivial, todavía gcc se queja (en -O3 -march=native
) sobre el despliegue del bucle:
cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations]
for(auto& plan : fw)
^
Aquí hay una versión (despojada de todas las cosas fftw, si no sería bastante larga) de mi código
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 = {};
};
Los vectores nunca superan un tamaño de 2 en mi código.
Edita según los comentarios: uso muchas banderas.
-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
No veo el sentido de hablar de poner infos sobre fftw_execute
aquí, pero si quiere ver todo el código (que juzgué demasiado largo para una publicación SO), está aquí: https://github.com/jcelerier/watermarking/blob/master/src/libwatermark/transform/FFTWManager.h
GCC: gcc version 4.8.2 (Debian 4.8.2-10)
No veo por qué cambiar de unsigned int a size_type cambiaría cualquier cosa, ya que no recibo ninguna advertencia en mi método setChannels
(incluso si creo que no tiene firma desde hace tiempo en mi plataforma) y una vez que se establece el tamaño, el tipo original de la variable que se utilizó para establecerlo me parece completamente irrelevante.
No hay ninguna advertencia con el básico for(int i = 0; i < bw.size(); i++)
o con la versión del iterador for(auto i = bw.begin(); i != bw.end(); i++)
También probé con clang, que parece reconocer el swich de advertencia, así que supongo que también implementaron la optimización, y no recibo ninguna advertencia (pero mucho más rápido de compilación).
Perdón por los comentarios largos, estaba fuera.
Desde el manual de gcc:
-funsafe-loop-optimizations
Esta opción le dice al optimizador de bucle que asuma que los índices de bucle no se desbordan, y que los bucles con condiciones de salida no triviales no son infinitos. Esto permite una gama más amplia de optimizaciones de bucle, incluso si el optimizador de bucle no puede demostrar que estas suposiciones son válidas. Si usa
-Wunsafe-loop-optimizations
, el compilador le advierte si encuentra este tipo de bucle.
Por lo tanto, aparentemente, la implementación del bucle range-for en el compilador se rompe de alguna manera, ya que desencadena esta advertencia. Podría deshabilitar esta advertencia en particular o deshabilitar esta optimización particular ... Aconsejaría esto último ya que no está claro si la optimización se realiza o no cuando se activa la advertencia.