2015-04-20 8 views
16

निम्नलिखित कार्यक्रम को देखते हुए।क्या std :: abs (0u) खराब गठित है?</p> <pre><code>#include <cmath> int main() { std::abs(0u) ; } </code></pre> <p><code>gcc</code> और <code>clang</code> इस बीमार का गठन किया गया है या पर असहमत:

error: call to 'abs' is ambiguous 
std::abs(0u) ; 
^~~~~~~~ 

कौन सा परिणाम सही है: libstdc++ साथ gcc कोड बनाता है यह उत्पन्न निम्न त्रुटि (see it live) libc++ साथ त्रुटि के बिना उपयोग करने या चेतावनी (see it live) है, जबकि clang का उपयोग कर? abs(0u) अस्पष्ट होना चाहिए या नहीं?


MSalters बताते हैं एक दिलचस्प संबंधित सवाल: Template version of std::abs

उत्तर

16

ऐसा लगता है कि libstdc++ सही है, यह बीमार नहीं है, हालांकि हम देखेंगे कि एलडब्ल्यूजी सक्रिय मुद्दे 2192 में यह एक दोष है या नहीं।

मसौदा सी ++ 11 मानक खंड 26.8[c.math] पैरा 11 का कहना है:

इसके अलावा, वहाँ अतिरिक्त भार के लिए पर्याप्त सुनिश्चित करने के लिए किया जाएगा:

और शामिल निम्नलिखित मद:

  1. अन्यथा, अगर कोई बहस एक डबल पैरामीटर से संबंधित मानसिक प्रकार में डबल या एक पूर्णांक प्रकार होता है, तो से संबंधित सभी तर्क प्रभावी रूप से डबल करने के लिए प्रभावी होते हैं।

और हम इस libstdc++ देख सकते हैं करता है indeed provide for this मामला:

:

template<typename _Tp> 
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                double>::__type 
abs(_Tp __x) 
{ return __builtin_fabs(__x); } 

एक भी एक gcc बग रिपोर्ट std::abs (long long) resorts to std::abs (double) if llabs is absent, जो सवालों के इस कार्यान्वयन सही है और एक प्रतिक्रिया कहते हैं अगर नहीं है

[...] मानक प्रति ठीक है, किसी भी पूर्णांक को बिना शर्त रूप से dou बन जाता है ble। [...]

बग रिपोर्ट अंततः LWG active issue 2192: Validity and return type of std::abs(0u) is unclear के लिए नेतृत्व दायर की जो अन्य बातों के साथ कहते हैं:

  1. 26,8 से सी ++ 11 अतिरिक्त "पर्याप्त अधिभार" नियम में [ग ।गणित] P11 (भी LWG 2086 देखें) std :: पेट (के लिए लागू होने के लिए पढ़ा जा सकता है) भार के रूप में अच्छी तरह है, जो निम्नलिखित संभव निष्कर्ष करने के लिए नेतृत्व कर सकते हैं:

कार्यक्रम

#include <type_traits> 
    #include <cmath> 

    static_assert(std::is_same<decltype(std::abs(0u)), double>(), "Oops"); 

    int main() { 
     std::abs(0u); // Calls std::abs(double) 
    } 

उप बुलेट 2 ("[..] या एक पूर्णांक प्रकार [..]") 26.8 [c.math] P11 के की वजह से, अच्छी तरह से गठित होना आवश्यक है (ध्यान दें कि वर्तमान संकल्प एलडब्ल्यूजी 2086 की इस समस्या को ठीक नहीं करता है)।

  1. अधिभार std :: abs (int) के रिटर्न प्रकार के लिए दो विरोधाभासी आवश्यकताओं के कारण दोनों अनुवाद और दोनों में बीमार हो सकता है।

मुझे ऐसा लगता है कि कम से कम दूसरा परिणाम इरादा नहीं है, व्यक्तिगत रूप से मुझे लगता है कि दोनों दुर्भाग्यपूर्ण है [...] यह भी होना चाहिए ने कहा कि इसी "सामान्य प्रकार समारोह" नियम सेट (लेकिन fabs कार्यों!) 7.25 p2 + 3 में C99/C1x से से फ्लोटिंग प्वाइंट कार्यों तक ही सीमित है और, इसलिए पेट कार्यों को लागू नहीं किया जा सकता है।

सवाल यह है कि क्या यह abs पर भी लागू होना था या नहीं। यह एक दोष हो सकता है क्योंकि abs को बाहर करने के लिए वर्तमान शब्द की व्याख्या करने का कोई तरीका प्रतीत नहीं होता है।

तो वर्तमान शब्द libstdc++ इंगित करता है अनुरूप है, यह स्पष्ट नहीं है कि libc++ ने अपना वर्तमान कार्यान्वयन क्यों चुना है। मुझे कोई विषय नहीं मिल रहा है और न ही इस विषय से जुड़े विचार-विमर्श और एलडब्ल्यूजी मुद्दे में विचलन कार्यान्वयन का उल्लेख नहीं है।

प्रस्तावित समाधान होगा std::abs(0u) बीमार का गठन:

पेट() अहस्ताक्षरित अभिन्न प्रकार है कि अभिन्न पदोन्नति द्वारा int करने के लिए नहीं बदला जा सकता का एक तर्क के साथ कॉल किया जाता है ([conv.prom]) , कार्यक्रम खराब गठित है। [नोट: तर्क int करने के लिए बढ़ावा दिया जा सकता सी साथ संगतता के लिए अनुमति दी जाती है - अंत टिप्पणी]

कुछ एक अहस्ताक्षरित प्रकार के साथ abs का उपयोग कर की धारणा पर सवाल खड़ा हो सकता है हावर्ड Hinnant रिपोर्ट में बताते हैं कि जब टेम्पलेट का उपयोग कर इस तरह के परिणाम स्पष्ट नहीं हो सकता है और एक उदाहरण देता है हो सकता है:

[...] विशेष रूप से C++ हम टेम्पलेट्स है, और प्रकार के शामिल हमेशा डिजाइन समय में प्रोग्रामर को स्पष्ट नहीं कर रहे हैं जहां। उदाहरण के लिए, पर विचार करें:

template <class Int> 
Int 
analyze(Int x, Int y) 
{ 
    // ... 
    if (std::abs(x - y) < threshold) 
    { 
    // ... 
    } 
    // ... 
} 
+0

[2192 एक दोष ले जाया गया था] (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2192) –

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