2013-10-17 24 views
13

Tôi cần lưu trữ một con trỏ duy nhất cho mỗi chuỗi sẽ được truy cập thông qua một macro. Tôi nghĩ rằng tôi nên giải quyết điều này với một đơn giản và tĩnh thread_local std :: unique_ptr đối tượng. Đây là một phiên bản đơn giản của các mã:C++ 11: GCC 4.8 tĩnh thread_local std :: unique_ptr undefined reference

main.cpp

#include <thread> 
#include <vector> 
#include <iostream> 
#include <mutex> 
using namespace std; 

#include "yay.hpp" 

mutex coutMutex; 

void yay(int id) 
{ 
    int* yayPtr = getYay(); 

    // I know this is bad 
    coutMutex.lock(); 
    cout << "Yay nr. " << id << " address: " << yayPtr << endl; 
    coutMutex.unlock(); 
} 

int main() 
{ 
    vector<thread> happy; 
    for(int i = 0; i < thread::hardware_concurrency(); i++) 
    { 
     happy.push_back(thread(yay, i)); 
    } 

    for(auto& smile : happy) 
    { 
     smile.join(); 
    } 
    return 0; 
} 

yay.hpp

#ifndef BE_HAPPY 
#define BE_HAPPY 

#include <memory> 
class Yay 
{ 
    private: 
     static thread_local std::unique_ptr<int> yay; 
     Yay() = delete; 
     Yay(const Yay&) = delete; 
     ~Yay() {} 
    public: 
     static int* getYay() 
     { 
      if(!yay.get()) 
      { 
       yay.reset(new int); 
      } 
      return yay.get(); 
     } 
}; 

#define getYay() Yay::getYay() 

#endif 

yay.cpp

#include "yay.hpp" 

thread_local std::unique_ptr<int> Yay::yay = nullptr; 

Nếu tôi biên dịch này với gcc 4.8 .1:

g++ -std=c++11 -pthread -o yay main.cpp yay.cpp 

tôi nhận được:

/tmp/cceSigGT.o: In function `_ZTWN3Yay3yayE': 
main.cpp:(.text._ZTWN3Yay3yayE[_ZTWN3Yay3yayE]+0x5): undefined reference to `_ZTHN3Yay3yayE' 
collect2: error: ld returned 1 exit status 

Tôi đã hy vọng tôi có thể nhận được thêm thông tin từ kêu vang, tuy nhiên nó hoạt động hoàn toàn tốt đẹp với vang 3.4:

clang++ -std=c++11 -pthread -o yay main.cpp yay.cpp 

Và chạy chương trình mang lại kết quả tôi đã mong đợi :

Yay nr. 2 address: 0x7fcd780008e0 
Yay nr. 0 address: 0x7fcd880008e0 
Yay nr. 1 address: 0x7fcd800008e0 
Yay nr. 3 address: 0x7fcd700008e0 
Yay nr. 4 address: 0x7fcd740008e0 
Yay nr. 5 address: 0x7fcd680008e0 
Yay nr. 6 address: 0x7fcd6c0008e0 
Yay nr. 7 address: 0x7fcd600008e0 

Tôi không chắc mình đang làm gì sai ở đây, không thể có thread_local unique_ptr obj tĩnh ect? Nó hoạt động với các kiểu đơn giản như int hoặc 'naked' con trỏ.

Edit:

Có thể rằng đây là một lỗi có liên quan đến http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55800

Edit2:

Giải pháp 1: biên dịch một file với kêu vang (yay.cpp)

Cách giải quyết 2 (khủng khiếp và không thể thay đổi): biên dịch yay.cpp để lắp ráp trước, thêm

.globl _ZTWN3Yay3yayE 
_ZTWN3Yay3yayE = __tls_init 

vào file lắp ráp, biên dịch cho đối tượng tập tin, kết nối với phần còn lại

+0

Có thể thay thế tiền xử lý của 'getYay()' đang làm bạn rối tung lên không? – Tom

+0

Không, nó không hoạt động nếu tôi xóa #define và gọi Yay :: getYay() trực tiếp. – linedot

+0

Trong báo cáo lỗi của bạn, bạn hiển thị một phiên bản giảm nhiều mã của bạn và giải pháp có thể có. Có lẽ bạn có thể đăng bài đó như một câu trả lời. –

Trả lời

2

tôi đã thử nghiệm với điều này bằng cách định nghĩa một do-gì ctor cho Yay trong Yay.hpp:

 
- Yay() = delete; 
+ Yay() {} 

Khi tôi đã làm điều đó, thông báo lỗi đã trở thành:

 
/tmp/cc8gDxIg.o: In function `TLS wrapper function for Yay::yay': 
main.cpp:(.text._ZTWN3Yay3yayE[_ZTWN3Yay3yayE]+0x5): undefined reference to `TLS init function for Yay::yay' 

Điều đó dẫn tôi đến GCC bug 55800. Lỗi này tồn tại trong các phiên bản GCC lên đến 4.8.2 và được sửa trong 4.8.3 và 4.9. Trong các chủ đề thảo luận tôi tìm thấy trên bản sao GCC bug 59364, quyết định đã được thực hiện để không quay lại khắc phục sự cố. Vì vậy, hack hội của bạn dường như là giải pháp duy nhất có sẵn cho đến khi bạn chuyển sang 4.9.

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