2012-03-30 8 views
7

In MS Visual C++ 2010 SP1 questo codice crash:std :: funzione si blocca quando usato in matrice sulla 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; 
} 

Quando il secondo elemento dell'array è costruito corrompe primo elemento dell'array.

È un errore nel compilatore o ho fatto qualcosa che non è supportato nello standard C++ 11?

EDIT

Questo codice funziona in 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

Non conosco la risposta, ma FWIW, funziona su GCC 4.6 dopo aver rimosso le specifiche MSVC. – Mat

+0

Grazie per il test con GCC 4.6. Ciò fornisce alcune prove per un bug nel compilatore MS. – frast

+0

I puntatori alle funzioni lambda sono in disordine, infatti, ho ridotto al minimo il problema in quel codice: #include #include int main (int argc, char * argv []) { \t std: : funzione s [] = { \t \t []() {std :: cout << "F0" << std :: endl;}, \t \t []() {int a = 1; std :: cout << "f1" << std :: endl;} \t}; \t s [0](); // output f1 invece di f0 \t s [1](); // Questo errore, il puntatore alla funzione è probabilmente incasinato return 0; } Quando si chiama s [0], esce "f1" E s [1] in realtà fallisce. – Mesop

risposta

2

Questo è un bug del compilatore. Non c'è niente di sbagliato nel tuo codice.

Il programma viene compilato ed eseguito senza errori utilizzando Visual C++ 11 Beta, quindi il bug sembra essere stato corretto per la prossima versione del compilatore.

+0

Speriamo che lo risolvano anche per VC 2010. Non possiamo usare C++ 11 perché i programmi compilati non funzionano su Windows XP. – frast

+0

@frast: non terrei il respiro. È superlativamente improbabile che ciò garantisca una patch per VC10, specialmente dal momento che esiste una semplice soluzione (ad esempio, usare 'std :: vector', come si fa nel secondo esempio, o inizializzare gli elementi dell'array singolarmente invece di usare l'inizializzazione aggregata) . –

0

Dove è il bit cattura? Se vuoi modificare a, non ti serve [& a] all'inizio del tuo primo lambda?

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

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

+0

'a' non dovrebbe essere catturato: è una variabile globale. –

+0

Se un non sarebbe accessibile allora dovrebbe essere un errore in fase di compilazione e non un errore in fase di esecuzione. – frast

Problemi correlati