2012-03-30 10 views
7

En MS Visual C++ 2010 SP1 este código se bloquea:std :: función se bloquea cuando se utiliza en conjunto en la pila

#include "stdafx.h" 

#include <functional> 
#include <iostream> 
//#include <vector> 

int a = 0; 

int _tmain(int argc, _TCHAR* argv[]) { 
    // this way it works: 
    //std::vector<std::function<void()>> s; 
    //s.push_back([]() { a = 1; }); 
    //s.push_back([]() { a = 2; int b = a; }); 

    std::function<void()> s[] = { 
     []() { a = 1; }, 
     []() { 
      a = 2; 

      // Problem occurs only if the following line is included. When commented out no problem occurs. 
      int b = a; 
     } 
    }; 

    int counter = 0; 
    for (auto it = std::begin(s); it != std::end(s); ++it) { 
     ++counter; 
     (*it)(); 
     std::wcout << counter << L":" << a << std::endl; 
    } 

    return 0; 
} 

Cuando el segundo elemento de matriz se construye corrompe el primer elemento de matriz.

¿Esto es un error en el compilador o he hecho algo que no es compatible con el estándar C++ 11?

EDITAR

Este código funciona en gcc-4.5.1:

#include <functional> 
#include <iostream> 
//#include <vector> 

int a = 0; 

int main(int argc, char* argv[]) { 
    // this way it works: 
    //std::vector<std::function<void()>> s; 
    //s.push_back([]() { a = 1; }); 
    //s.push_back([]() { a = 2; int b = a; }); 

    std::function<void()> s[] = { 
     []() { a = 1; }, 
     []() { 
      a = 2; 

      // Problem occurs only if the following line is included. 
      //When commented out no problem occurs. 
      int b = a; 
     } 
    }; 

    int counter = 0; 
    ++counter; 
    s[0](); 
    std::wcout << counter << L":" << a << std::endl; 
    ++counter; 
    s[1](); 
    std::wcout << counter << L":" << a << std::endl; 

    return 0; 
} 
+2

No sé la respuesta pero FWIW, funciona en GCC 4.6 una vez que haya eliminado los detalles de MSVC. – Mat

+0

Gracias por probar con GCC 4.6. Esto proporciona alguna evidencia de un error en el compilador de MS. – frast

+0

Los punteros a las funciones lambda están en mal estado, de hecho, Minimicé el problema en ese código: # include # include int main (int argc, char * argv []) { \t std: : función s [] = { \t \t []() {std :: cout << "f0" << std :: endl;}, \t \t []() {int a = 1; std :: cout << "f1" << std :: endl;} \t}; \t s [0](); // salida f1 en lugar de f0 \t s [1](); // Este falló, el puntero a la función probablemente está en mal estado return 0; } Cuando llama a s [0], muestra "f1" Y s [1] realmente falla. – Mesop

Respuesta

2

Esto es un error del compilador. No hay nada malo con tu código.

Su programa se compila y se ejecuta sin errores utilizando la versión Beta de Visual C++ 11, por lo que parece que el error se corrigió en la próxima versión del compilador.

+0

Esperemos que lo arreglen para VC 2010 también. No podemos usar C++ 11 porque los programas compilados no se ejecutan en Windows XP. – frast

+0

@frast: No aguantaría la respiración. Es superlativamente improbable que esto justifique un parche para VC10, especialmente porque hay una solución directa (por ejemplo, use 'std :: vector', como lo hace en su segundo ejemplo, o inicialice los elementos de la matriz individualmente en lugar de usar la inicialización agregada) . –

0

¿Dónde está el bit de captura? Si desea modificar una, ¿no necesita [& a] al comienzo de su primera lambda?

[&a]() { a = 1; }, 

http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B

+0

'a' no debería ser capturado: es una variable global. –

+0

Si no se puede acceder a un, entonces debería ser un error en tiempo de compilación y no un error en tiempo de ejecución. – frast

Cuestiones relacionadas