2013-10-17 13 views
13

मुझे मैक्रो के माध्यम से उपयोग किए जाने वाले प्रत्येक थ्रेड के लिए एक अद्वितीय सूचक स्टोर करने की आवश्यकता है। मैंने सोचा कि मुझे इसे सिंगलटन और स्थिर थ्रेड_लोकल std :: unique_ptr ऑब्जेक्ट्स के साथ हल करना चाहिए। यहाँ कोड का एक सरलीकृत संस्करण है:सी ++ 11: जीसीसी 4.8 स्थिर थ्रेड_लोकल std :: unique_ptr अपरिभाषित संदर्भ

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; 

मैं जीसीसी 4.8 के साथ इस संकलन हैं .1:

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

मैं:

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

मुझे उम्मीद थी मैं बजना से और अधिक जानकारी प्राप्त कर सकते हैं, लेकिन यह बजना 3.4 के साथ पूरी तरह ठीक काम करता है:

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

और कार्यक्रम चलाने परिणाम मैं उम्मीद कर रहा था पैदावार :

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 

मुझे यकीन है कि मैं गलत यहाँ क्या कर रहा हूँ नहीं कर रहा हूँ, है ना स्थिर thread_local unique_ptr obj करना संभव है ECTS? यह int या 'नग्न' पॉइंटर्स जैसे साधारण प्रकारों के साथ काम करता है।

संपादित करें:

ऐसा नहीं है कि यह एक बग है कि http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55800

EDIT2 से संबंधित है संभव है:

वर्कअराउंड 1: बजना के साथ एक फ़ाइल संकलन (yay.cpp)

वर्कअराउंड 2 (भयानक और अप्राप्य): yay.cpp को पहले असेंबली में संकलित करें,

.globl _ZTWN3Yay3yayE 
_ZTWN3Yay3yayE = __tls_init 

विधानसभा फाइल करने के लिए, फ़ाइल आपत्ति उठाने का संकलन, बाकी

+0

क्या यह संभव है कि 'getYay() 'के प्रीप्रोसेसर प्रतिस्थापन आपको गड़बड़ कर रहा है? – Tom

+0

नहीं, अगर मैं #define को हटा देता हूं और Yay :: getYay() को सीधे कॉल करता हूं तो यह काम नहीं करता है। – linedot

+0

अपनी बग रिपोर्ट में आप अपने कोड का एक बहुत कम संस्करण और एक संभावित कामकाज दिखाते हैं। शायद आप इसे एक उत्तर के रूप में पोस्ट कर सकते हैं। –

उत्तर

2

मैं Yay.hpp में Yay के लिए एक do-कुछ भी नहीं ctor को परिभाषित करते हुए इस के साथ प्रयोग के साथ लिंक:

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

जब मैंने वह किया, त्रुटि संदेश बने:

 
/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' 

जो मुझे GCC bug 55800 का नेतृत्व किया। बग जीसीसी संस्करणों में 4.8.2 के माध्यम से मौजूद है, और यह 4.8.3 और 4.9 में तय किया गया है। चर्चा धागे में मैंने डुप्लिकेट GCC bug 59364 पर पाया, निर्णय को ठीक करने के लिए पोर्ट को वापस नहीं किया गया है। इसलिए, जब तक आप 4.9 तक नहीं जाते हैं, तब तक आपका असेंबलर हैक उपलब्ध एकमात्र समाधान प्रतीत होता है।

संबंधित मुद्दे