2015-08-14 7 views
5

मैंने इसे गोगल किया & ने SO पर भी इसी तरह के प्रश्न को खोजने का प्रयास किया लेकिन कुछ भी उपयोगी नहीं मिला। तो, यहां मेरा प्रश्न पोस्ट कर रहा है।स्ट्रिंग के लिए बूल का निहित रूपांतरण क्यों त्रुटि नहीं है?

#include <iostream> 
void foo(const std::string &) {} 
int main() 
{ 
    foo(false); 
} 
 
[Warning] converting 'false' to pointer type for argument 1 of 'std::basic_string::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' [-Wconversion-null] 

क्यों सी ++ इस स्पष्ट कलाकारों के बिना अनुमति देता है:

इस कार्यक्रम पर विचार करें? मैं संकलक त्रुटि प्राप्त करने की उम्मीद कर रहा था।

terminate called after throwing an instance of 'std::logic_error' 
    what(): basic_string::_S_construct null not valid 

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 

मानक अंतर्निहित रूपांतरण के इस प्रकार के बारे में क्या कहते हैं: कार्यक्रम असामान्य रूप से प्रदर्शित निम्न अपवाद के कारण कार्यावधि में समाप्त हो जाता है?

+1

"इस प्रकार के निहित रूपांतरण के बारे में मानक क्या कहता है?" यह कहता है कि इसकी अनुमति है। – juanchopanza

+0

@juanchopanza: नहीं। ऐसा नहीं है। आपको सी ++ मानक से प्रासंगिक पाठ लिखना होगा। – Destructor

+5

@ डाउनवॉटर: क्यों डाउनवॉट्स? सवाल में क्या गलत है? – Destructor

उत्तर

7

सी ++ 11 से पहले nullptr कीवर्ड पेश किया गया, शून्य पॉइंटर्स एक हैक का थोड़ा सा था। किसी भी पूर्णांक शून्य के बराबर शून्य शून्य शून्य सूचकांक के रूप में पर्याप्त होगा, और false बिल फिट होगा।

तो, आपके प्रोग्राम का प्रभाव std::stringNULL के char const * तर्क के साथ बनाना है। कन्स्ट्रक्टर नल पॉइंटर्स का समर्थन नहीं करता है, इसलिए आपको अपरिभाषित व्यवहार मिलता है।

इस समस्या का समाधान C++ की एक नई बोली का उपयोग करना है। यदि आवश्यक हो तो संकलक को -std=c++11 पास करें, या -std=c++14।तो फिर तुम कुछ इस तरह मिलना चाहिए:

error: no matching function for call to 'foo' 

http://coliru.stacked-crooked.com/a/7f3048229a1d0e5a

संपादित करें: हम्म, जीसीसी अभी तक इस परिवर्तन को लागू करने प्रकट नहीं होता है। यह थोड़ा आश्चर्यजनक है। आप क्लैंग का प्रयास कर सकते हैं।

मेरे पास filed एक बग रिपोर्ट है।

+1

जीसीसी अभी भी इसे सी ++ 11 या सी ++ 14 सक्षम के साथ संकलित करता है। – Quentin

+3

@ क्वांटिन, यह एक निदान जारी करता है, जो तकनीकी रूप से एक बीमार गठित कार्यक्रम के लिए आवश्यक है। मैं पसंद करता हूं अगर यह एक त्रुटि थी हालांकि चेतावनी नहीं थी। –

+2

@ जोनाथन वाक्ली लेकिन एसएफआईएनएई और अधिभार आंशिक क्रम के बारे में क्या? मैं अब एक विशिष्ट उदाहरण के साथ परीक्षण करने के लिए आलसी हूँ, क्षमा करें। – Potatoswatter

-1

एक bool मूल रूप से एक पूर्णांक तो यह आपके मामले में यह शायद है 0 चरित्र एक शून्य के रूप में व्याख्या की जाएगी, और इस समस्या है कि स्ट्रिंग का कारण होगा होगा एक अपवाद

3

क्या होता है एक std::string है कि false से अधिभार का उपयोग करके false को एक शून्य सूचक में परिवर्तित करके false से अंतर्निहित रूप से बनाया गया। कि निर्माता के लिए प्रलेखन के अनुसार:

व्यवहार अपरिभाषित है अगर s [सूचक] CharT के कम से कम Traits::length(s)+1 तत्वों की एक सरणी में इंगित नहीं करता है।

इसलिए खराब (एक दोस्ताना अपवाद के रूप में है, लेकिन यह पर भरोसा नहीं है)।

अब, क्या यह सही है? [Conv.ptr] के अनुसार:

एक नल पॉइंटर निरंतर एक पूर्णांक शाब्दिक (2.13.2) मान शून्य या प्रकार std::nullptr_t के prvalue के साथ है।

false वास्तव में शून्य का मान है, लेकिन यह एक पूर्णांक अक्षर नहीं है (यह एक बूलियन शाब्दिक है)। CharT* पर अंतर्निहित रूपांतरण std::string का कन्स्ट्रक्टर इस प्रकार गैर-मानक है।

और वास्तव में, जबकि जीसीसी एक चेतावनी उत्सर्जित करता है, क्लैंग इसे संकलित करने से इंकार कर देता है।

+2

क्लैंग इसे संकलित करता है यदि आप '-std = C++ 03' निर्दिष्ट करते हैं। यह सिर्फ निर्भर करता है कि कौन सा बोली विशेष संकलक संस्करण के लिए डिफ़ॉल्ट है। – Potatoswatter

+0

@ पोटाटोस्वाटर लेकिन सवाल सी ++ 03 का उल्लेख नहीं करता है। सी ++ 11 और उसके बाद, केवल शाब्दिक '0' को शून्य सूचक में परिवर्तित किया जा सकता है। – Quentin

+0

@ क्वांटिन: आप क्यों कह रहे हैं कि अनुकूल अपवाद के रूप में भरोसा न करें? – Destructor

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