2012-08-11 21 views
6

पर व्युत्पन्न अपवाद प्रकारों को पकड़ना विफल रहता है मेरे पास एक सी ++ लाइब्रेरी है जिसे मैं क्लैंग के साथ मैक ओएस एक्स पर चलने की कोशिश कर रहा हूं। पुस्तकालय में एक डीएलएल और यूनिट-टेस्ट निष्पादन योग्य होता है। यह जीसीसी और MSVC के साथ ठीक संकलित, जीसीसी के साथ, मैं निम्नलिखित सेटिंग्स का उपयोग करें:क्लैंग/मैकोज़ एक्स

  • पुस्तकालय -fvisibility=hidden
  • साथ संकलित किया गया है सभी संपर्क में कक्षाएं स्पष्ट __attribute__(visibility("default"))
  • पुस्तकालय कुछ अपवाद वर्ग हैं के रूप में चिह्नित कर रहे हैं, std::runtime_error से व्युत्पन्न। ऐसे सभी वर्ग डिफ़ॉल्ट दृश्यता के लिए चिह्नित हैं। एक रूट क्लास LibraryException है जिसमें से अधिक विशिष्ट अपवाद प्राप्त किए जाते हैं।
  • जीसीसी पर, मैं -std=c++0x उपयोग करते हैं, बजना के साथ, दोनों पुस्तकालय और इकाई परीक्षण निष्पादन के साथ -stdlib=libc++ -std=c++11

मैक ओएस एक्स पर, इकाई परीक्षण ढांचा अब विफल रहता है बनाया गया है, क्योंकि अपवाद गलत प्रकार के होते हैं । अर्थात। इस तरह के एक परीक्षण में विफल रहता है:

// bla.foo() throws CustomException, which is derived from LibraryException 
TEST_THROWS (bla.foo(), CustomException) 

// This works however 
TEST_THROWS (bla.foo(), LibraryException) 

मैं सत्यापित है कि typeinfo और अपने कस्टम अपवाद वर्गों के vtable nm -g library.dylib | c++filt -p -i का उपयोग कर निर्यात किया जाता है। ऐसा लगता है कि सभी अपवादों के लिए मामला क्या है ... यहाँ बिल्ली क्या चल रहा है? मैंने त्रुटियों पर डीबग करने का प्रयास किया है, और मैं देखता हूं कि लाइब्रेरी में सही प्रकार कैसे डाला जा रहा है और फिर भी यूनिट परीक्षण निष्पादन योग्य में उसी प्रकार को पकड़ा नहीं जा सकता है। क्या यह काम करने के लिए क्लैंग के साथ कुछ विशेष आवश्यकता है? मैं परीक्षण के लिए एसवीएन से नवीनतम googletest ढांचे का उपयोग कर रहा हूँ।

try { 
    funcThatThrowsCustomExceptionFromLibraryDylib(); 
} catch (CustomException& e) { 
    // doesn't get here 
} catch (LibraryException& e) { 
    // does get here 
    // after demangle, this prints CustomException 
    // Can cast down to CustomException and access the fields as well 
    std::cout << typeid (e).name() << "\n"; 
} 

यह भी जब एक boost::lexical_cast अपवाद लाइब्रेरी से फेंक दिया जाता है, उदाहरण के लिए विफल रहता है:

एक छोटी सी परीक्षण कार्यक्रम एक ही समस्या दर्शाती है।

उत्तर

3

यहाँ सही समाधान है:

जब दृश्यता विशेषता लागू करने के लिए, यह लागू किया जाना चाहिए दोनों जब पुस्तकालय के रूप में अच्छी तरह से संकलित किया गया है, जब यह सेवन किया जाता है। अन्यथा, ग्राहक कक्षाओं को नहीं देख पाएंगे। बढ़ावा :: lexical_cast के लिए, यह मतलब है कि आप

#pragma GCC visibility push(default) 
#include <boost/lexical_cast.hpp> 
#pragma GCC visibility pop 

उपयोग करने के लिए जब तक वे यह (अपवाद के लिए एक __attribute((visibility("default"))) जोड़ने बूस्ट 1.50 के रूप में द्वारा पुस्तकालय में ठीक किया गया मिलता है, विशेषता मौजूद है, लेकिन ऐसा लगता है कि क्लैंग के लिए समर्थन अभी तक नहीं है)। लाइब्रेरी में हेडर में इसका उपयोग करते समय, इसे क्लाइंट कोड में ठीक से पकड़ा जा सकता है। यह #pragma क्लैंग के साथ भी काम करता है।

तथ्य यह है कि एक फेंक() विनाशक को निर्दिष्ट करने में मदद कुछ भाग्य थी, लेकिन यह निश्चित रूप से सही तय नहीं है।

+0

निश्चित रूप से एक बग की तरह दिखता है ... क्या आपने स्वयं विनाशक को फिर से बनाया है या क्या यह डिफ़ॉल्ट रूप से निर्मित है? जीसीसी 4.3.2 के साथ मुझे चेतावनी मिलती है अगर मैं 'अपवाद' से विरासत में 'फेंक()' विनिर्देशक के बिना विनाशक घोषित करता हूं। –

+0

मैंने लाइब्रेरीएक्सप्शन में ~ लाइब्रेरीएक्सप्शन() फेंक() के रूप में इसे दोबारा शुरू किया; अन्यथा, जीसीसी 4.6 ने शिकायत की कि डिफ़ॉल्ट व्यक्ति में गलत फेंक विनिर्देश या कुछ समान है। – Anteru

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

  • कोई संबंधित समस्या नहीं^_^