पर एक -फनो-आरटीआई साझा लाइब्रेरी में अपवाद को पकड़ने के लिए पॉलिमॉर्फिक रूप से f-no-rtti
के साथ साझा लाइब्रेरी का निर्माण कर रहा हूं। आंतरिक रूप से, यह लाइब्रेरी std:invalid_argument
फेंकता है और std::exception
पकड़ता है, लेकिन catch
खंड कभी दर्ज नहीं किया जाता है।मैक ओएस एक्स
निम्नलिखित कोड समस्या reproduces (छ ++ 4.2, मैक ओएस एक्स 10.6):
// library.cpp: exports f(), compiled with -fno-rtti
#include <stdexcept>
#include <iostream>
extern "C" {
void f() {
try {
throw std::invalid_argument("std::exception handler");
} catch(std::exception& e) {
std::cout << e.what() << "\n";
} catch(...) {
std::cout << "... handler\n";
}
}
}
// main.cpp: the main executable, dynamically loads the library
#include <dlfcn.h>
typedef void(*fPtr)();
int main() {
void* handle = dlopen("./libexception_problem.dylib", RTLD_LAZY);
fPtr p_f = reinterpret_cast<fPtr>(dlsym(handle, "f"));
p_f();
}
आउटपुट:
MacBook-Pro:teste pfranco$ # works fine with rtti
MacBook-Pro:teste pfranco$ g++ -c library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ main.cpp -o main && ./main
std::exception handler
MacBook-Pro:teste pfranco$ # breaks with -fno-rtti
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ #-no_dead_strip_inits_and_terms doesn't change anything
MacBook-Pro:teste pfranco$ g++ -c -no_dead_strip_inits_and_terms -fno-rtti library.cpp && g++ -no_dead_strip_inits_and_terms -shared -o libexception_problem.dylib library.o && g++ -fno-rtti -no_dead_strip_inits_and_terms main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ # linking against the shared library works, but this isn't always an option
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main -L. -lexception_problem && ./main
std::exception handler
यह केवल तभी होता है जब साझा लाइब्रेरी में साझा किया गया कोड, और केवल तभी पकड़ा गया प्रकार वास्तविक वर्ग वास्तविक अपवाद - catch(std::invalid_argument&)
ठीक काम करता है, std::logic_error&
नहीं करता है।
दिलचस्प बात यह है कि यह लिनक्स पर नहीं होता है, यहां तक कि सटीक वही आदेश चलाते समय भी।
सवाल:
- इस क्यों होता है? क्या यह एक बग, अपरिभाषित व्यवहार या डिजाइन द्वारा है?
- पुस्तकालय के खिलाफ जोड़ने से कम, मैं इसे कैसे काम कर सकता हूं?
बहुत बहुत धन्यवाद।
यदि "अपरिभाषित व्यवहार" से आपका मतलब सी ++ मानक के अनुसार है, तो यह कार्यान्वयन-परिभाषित है जब आप एक कंपाइलर विकल्प का उपयोग करते हैं जो संकलक को गैर-अनुपालन मोड में रखता है।मुझे संदेह है कि आपको बहुत मदद मिलती है, लेकिन आप मानक के बिट्स को अक्षम नहीं कर सकते हैं और फिर मानक की आपकी मदद करने की उम्मीद कर सकते हैं ;-) –