2012-03-30 24 views
7

Trong MS Visual C++ 2010 SP1 mã này tai nạn:std :: chức năng bị treo khi sử dụng trong mảng trên stack

#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; 
} 

Khi phần tử mảng thứ hai được xây dựng nó corrupts phần tử mảng đầu tiên.

Đây có phải là lỗi trong trình biên dịch hay tôi đã làm điều gì đó không được hỗ trợ trong tiêu chuẩn C++ 11?

EDIT

Mã này hoạt động trong 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

Tôi không biết câu trả lời nhưng FWIW, hoạt động trên GCC 4.6 khi bạn đã loại bỏ các chi tiết cụ thể của MSVC. – Mat

+0

Cảm ơn bạn đã thử nghiệm với GCC 4.6. Điều này cho một số bằng chứng cho một lỗi trong trình biên dịch MS. – frast

+0

Các con trỏ đến các chức năng lambda được sai lầm trong thực tế, tôi hạn chế tối đa các vấn đề thành mã: #include #include int main (int argc, char * argv []) { \t std: : function s [] = { \t \t []() {std :: cout << "f0" << std :: endl;}, \t \t []() {int a = 1; std :: cout << "f1" << std :: endl;} \t}; \t s [0](); // đầu ra f1 thay vì f0 \t s [1](); // Điều này không thành công, con trỏ đến hàm có thể bị sai lệch trả về 0; } Khi bạn gọi s [0], nó ouput "f1" Và s [1] thực sự không thành công. – Mesop

Trả lời

2

Đây là một lỗi biên dịch. Không có gì sai với mã của bạn.

Chương trình của bạn biên dịch và chạy mà không gặp lỗi khi sử dụng Visual C++ 11 Beta, do đó lỗi này dường như đã được sửa cho bản phát hành sắp tới của trình biên dịch.

+0

Cho phép hy vọng họ cũng sửa nó cho VC 2010. Chúng tôi không thể sử dụng C++ 11 vì các chương trình đã biên dịch không chạy trên Windows XP. – frast

+0

@frast: Tôi sẽ không nín thở. Không thể chắc chắn rằng điều này sẽ đảm bảo một bản vá cho VC10, đặc biệt vì có một cách giải quyết đơn giản (ví dụ, sử dụng 'std :: vector', như bạn làm trong ví dụ thứ hai của bạn, hoặc khởi tạo các phần tử mảng riêng lẻ thay vì sử dụng khởi tạo tổng hợp) . –

0

đâu là bit chụp? Nếu bạn muốn sửa đổi một, bạn không cần [& a] vào đầu lambda đầu tiên của bạn?

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

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

+0

'a' không cần phải bị bắt: đó là biến toàn cục. –

+0

Nếu không thể truy cập được thì đó phải là lỗi biên dịch và không phải là lỗi thời gian chạy. – frast

Các vấn đề liên quan