c++ c++11 lambda arm compiler-bug

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 la App )
  • 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?