c++ - "Esto" capturado por lambda es incorrecto. GCC compiler bug?
c++11 arm (2)
Esto parece ser un error de compilación en gcc 6.2, ver:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77686
Soluciones:
- Use el
-fno-schedule-insns2
(como lo señala gbmhunter, vea el comentario a continuación). - No utilice optimizaciones de
-O2
o superior.
Durante los últimos días, he estado depurando un problema extraño relacionado con las lambdas en C ++. He reducido el problema a los siguientes síntomas:
- El puntero de
this
se corrompe dentro de un lambda (nota:this
siempre se captura mediante copia, por lo que el lambda debe obtener su propio puntero, que apunta al objeto de laApp
) - Solo ocurre si hay una sentencia
std::cout
print presente y se llama antes de que se cree la lambda. La declaración de impresión puede ser aparentemente no relacionada (p. Ej., Imprimir "¡Hola!").printf()
también exhibe el mismo comportamiento. - Sólo ocurre cuando se compila de forma cruzada.
- Compila y funciona bien con el compilador estándar para la arquitectura
x86
(ver example ). - Si creo la lambda en el montón (y guardo un puntero dentro del objeto de la
App
), no se produce el error. - El error no se produce si las optimizaciones están desactivadas (es decir, si configuro el indicador
-O0
). Ocurre cuando la optimización se establece en-O2
.
El siguiente es el ejemplo de código compilable más simple que podría encontrar que causa el problema.
#include <iostream>
#include <functional>
class App {
public:
std::function<void*()> test_;
void Run() {
// Enable this line, ERROR is printed
// Disable this line, app runs o.k.
std::cout << "This print statement causes the bug below!" << std::endl;
test_ = [this] () {
return this;
};
void* returnedThis = test_();
if(returnedThis != this) {
std::cout << "ERROR: ''this'' returned from lambda (" << returnedThis
<< ") is NOT the same as ''this'' (" << this << ") !?!?!?!?!"
<< std::endl;
} else {
std::cout << "Program run successfully." << std::endl;
}
}
};
int main(void) {
App app;
app.Run();
}
Cuando se ejecuta en el dispositivo de destino, obtengo el siguiente resultado:
This print statement causes the bug below!
ERROR: ''this'' returned from lambda (0xbec92dd4) is NOT the same as ''this''
(0xbec92c68) !?!?!?!?!
Si trato de desreferenciarlo, this
dañado, generalmente me sale una falla de segmentación, que es como descubrí el error en primer lugar.
Configuraciones del compilador
arm-poky-linux-gnueabi-g++ -march=armv7-a -marm -mfpu=neon -std=c++14 /
-mfloat-abi=hard -mcpu=cortex-a9 /
--sysroot=/home/ghunter/sysroots/cortexa9hf-neon-poky-linux-gnueabi /
-O2 -pipe -g -feliminate-unused-debug-types
Configuraciones del enlazador
arm-poky-linux-gnueabi-ld /
--sysroot=/home/ghunter/sysroots/cortexa9hf-neon-poky-linux-gnueabi /
-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed
Versión del compilador
~$ arm-poky-linux-gnueabi-g++ --version
arm-poky-linux-gnueabi-g++ (GCC) 6.2.0
Copyright (C) 2016 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.
¿Podría ser esto un error de compilación?
Suena como el siguiente error del compilador: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77933 (que solo afecta al código generado con optimizaciones O1 o superior).