निम्नलिखित कार्यक्रम पर विचार करें:
#include<stdexcept>
#include<iostream>
int main() {
try {
throw std::range_error(nullptr);
} catch(const std::range_error&) {
std::cout << "Caught!\n";
}
}
GCC और Clang libstdc ++ के साथ कॉल करें std::terminate
और संदेश के साथ कार्यक्रम को रद्द करें
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
अपवाद के निर्माण पर libc ++ segfaults के साथ क्लैंग।
देवभूमि को देखें ।
क्या कंपाइलर मानक-अनुरूप व्यवहार कर रहे हैं? मानक के संबंधित खंड [diagnostics.range.error] (C ++ 17 N4659) का कहना है कि std::range_error
एक रचनाकार const char*
अधिभार है जिसे अधिभार के ऊपर पसंद किया जाना चाहिए const std::string&
। खंड भी निर्माता पर कोई पूर्व शर्त नहीं बताता है और केवल पोस्टकंडिशन बताता है
Postconditions :
strcmp(what(), what_arg) == 0
।
इस पोस्टकंडिशन में हमेशा what_arg
अशक्त व्यवहार होता है यदि एक अशक्त सूचक है, तो क्या इसका मतलब यह है कि मेरे कार्यक्रम में भी अपरिभाषित व्यवहार है और दोनों संकलक अनुरूप हैं? यदि नहीं, तो मानक में ऐसे असंभव पोस्टकंडिशन को कैसे पढ़ा जाना चाहिए?
दूसरे विचार पर, मुझे लगता है कि इसका मेरे कार्यक्रम के लिए अपरिभाषित व्यवहार का मतलब होना चाहिए, क्योंकि अगर ऐसा नहीं होता तो (वैध) संकेत शून्य-निरूपित तारों की ओर इशारा नहीं करते, जो स्पष्ट रूप से कोई मतलब नहीं है।
इसलिए, यह मानते हुए कि यह सच है, मैं इस सवाल पर अधिक ध्यान केंद्रित करना चाहता हूं कि मानक इस अपरिभाषित व्यवहार को कैसे दर्शाता है। क्या यह पोस्टकॉन्डिशन की असंभवता का पालन करता है कि कॉल में अपरिभाषित व्यवहार भी है या क्या पूर्व शर्त बस भूल गई थी?
इस सवाल से प्रेरित ।
nullptr
पारित हो जाता है, तो मुझे लगता है कि what()
मूल्य प्राप्त करने के लिए इसे किसी बिंदु पर इसे रोकना होगा। यह एक dereferencing होगा nullptr
, जो कि सबसे अच्छा समस्याग्रस्त है और निश्चित रूप से क्रैश सबसे खराब हैं।
strcmp
इसका उपयोग मूल्य का वर्णन करने के लिए किया जाता है what_arg
। सी मानक से प्रासंगिक अनुभाग वैसे भी कहते हैं, जिसे विनिर्देशन द्वारा निर्दिष्ट किया गया है <cstring>
। बेशक शब्दांकन स्पष्ट हो सकता है।
what()
जब पास कियाnullptr
जाता है तो कॉल करने से शायद समस्या होती है।