2015-10-05 10 views
11

मैं कोड का निम्न भाग है:घटाव पर हस्ताक्षर किए देता

#include <cstdint> 

template <typename T> 
T test(T a, T b) 
{ 
    float aabb = reinterpret_cast<float>(a - b); 
} 

int main(int argc, const char *argv[]) 
{ 
    std::uint8_t a8, b8; 
    test(a8, b8); 
    return 0; 
} 

मुझे पता है कि reinterpret_cast<float> काम नहीं कर सकता और यह संकलन समय पर त्रुटि देता है। मैं उस त्रुटि का उपयोग कर रहा हूं ताकि संकलक मुझे a - b का प्रकार बताए।

समस्या यह है कि इस मामले में, यह कहता है कि a - b का प्रकार int है जब दोनों uint8_t (unsigned char) हैं। uint16_t के साथ ऐसा ही होता है। लेकिन uint32_t के साथ नहीं जो यह कहता है कि a - bunsigned int है।

तो, मेरा सवाल यह है: क्या यह इरादा व्यवहार है (जो हस्ताक्षरित चार - हस्ताक्षरित चार एक int देता है), या यह किसी प्रकार का अजीब कंपाइलर बग है (जीसीसी और क्लैंग दोनों के साथ परीक्षण किया गया है)?

+3

यह लगता है [प्रासंगिक] (http://stackoverflow.com/questions/29817927/why-are-integer-types-promoted-during-addition-in-c?rq=1) (पदोन्नति सी और सी ++ में कम से कम समान है, अगर ऐसा नहीं है)। – chris

+1

हाँ, 'int' से छोटा कोई भी प्रकार अंकगणित के लिए 'int' को बढ़ावा देता है। – ShadowRanger

+0

'reinterpret_cast' से बचें, यह कार्यान्वयन-परिभाषित है। – vsoftco

उत्तर

11

हाँ, यह तथाकथित सामान्य गणित रूपांतरणअभिन्न पदोन्नति के लिए नियमों के साथ संयुक्त के हिस्से के रूप की उम्मीद है,।

सी ++ 03 और सी ++ 11 के बीच सटीक शब्द बदल गया, लेकिन अंतिम परिणाम इस मामले में समान है।


[C++03: 4.5/1]: प्रकार char, signed char, unsigned char, short int, या अहस्ताक्षरित short int का एक rvalue प्रकार int के एक rvalue में बदला जा सकता है, तो int स्रोत प्रकार के सभी मूल्यों का प्रतिनिधित्व कर सकते हैं; अन्यथा, स्रोत रावल्यू को unsigned int प्रकार के रैवल्यू में परिवर्तित किया जा सकता है।

[C++03: 4.5/5]: ये रूपांतरण अभिन्न पदोन्नति कहा जाता है।

[C++03: 5/9]: कई बाइनरी ऑपरेटरों जो अंकगणित या गणना प्रकार के संचालन की अपेक्षा करते हैं रूपांतरण और उपज परिणाम प्रकार इसी तरह से होते हैं। इसका उद्देश्य एक आम प्रकार पैदा करना है, जो परिणाम का भी प्रकार है। या तो संकार्य प्रकार long double की है

  • हैं, तो अन्य long double करने के लिए परिवर्तित किया जाएगा:

    यह पैटर्न सामान्य गणित रूपांतरण, जो परिभाषित कर रहे हैं इस प्रकार कहा जाता है।

  • अन्यथा, यदि ऑपरेंड double है, तो दूसरा डबल में परिवर्तित हो जाएगा।
  • अन्यथा, यदि ऑपरेंड float है, तो दूसरा float में परिवर्तित हो जाएगा।
  • अन्यथा, अभिन्न प्रचार (4.5) दोनों ऑपरेटरों पर किया जाएगा।
  • फिर, यदि ऑपरेंड unsigned long है तो दूसरा unsigned long में परिवर्तित हो जाएगा।
  • अन्यथा, यदि एक संकार्य एक long int और अन्य unsigned int है, तो अगर एक long int एक अहस्ताक्षरित पूर्णांक के सभी मूल्यों का प्रतिनिधित्व कर सकते हैं, अहस्ताक्षरित int एक long int करने के लिए परिवर्तित किया जाएगा; अन्यथा दोनों ऑपरेटरों को हस्ताक्षर किए गए long int में परिवर्तित कर दिया जाएगा।
  • अन्यथा, यदि ऑपरेंड long है, तो दूसरा long में परिवर्तित हो जाएगा।
  • अन्यथा, यदि ऑपरेंड unsigned है, तो दूसरा unsigned में परिवर्तित हो जाएगा।

[नोट: अन्यथा, केवल शेष मामला है कि दोनों ऑपरेंड हैं int]


[C++11: 4.5/1]: एक पूर्णांक से bool, char16_t अन्य प्रकार का एक prvalue, char32_t, या wchar_t जिसका पूर्णांक रूपांतरण रैंक (4.13)के रैंक से कम हैint के प्रकार के रूप में परिवर्तित किया जा सकता है यदि int स्रोत प्रकार के सभी मानों का प्रतिनिधित्व कर सकता है; अन्यथा, स्रोत प्रसार को बिना किसी हस्ताक्षर किए गए int के रूप में परिवर्तित किया जा सकता है।

[C++11: 4.5/7]: इन रूपांतरणों को अभिन्न प्रचार कहा जाता है।

[C++11: 5.9]: कई बाइनरी ऑपरेटरों जो अंकगणित या गणना प्रकार के संचालन की अपेक्षा करते हैं रूपांतरण और उपज परिणाम प्रकार इसी तरह से होते हैं। इसका उद्देश्य एक आम प्रकार पैदा करना है, जो परिणाम का भी प्रकार है।

यह पैटर्न सामान्य गणित रूपांतरण, जो परिभाषित कर रहे हैं इस प्रकार कहा जाता है: या तो संकार्य scoped गणना प्रकार (7.2) की है

  • तो कोई भी रूपांतरण किया जाता है; यदि अन्य ऑपरेंड में एक ही प्रकार नहीं है, तो अभिव्यक्ति खराब है।
  • यदि या तो ऑपरेंड लंबे समय तक डबल होता है, तो दूसरा लंबा डबल में परिवर्तित हो जाएगा।
  • अन्यथा, यदि ऑपरेंड डबल है, तो दूसरा डबल में परिवर्तित हो जाएगा।
  • अन्यथा, अगर ऑपरेंड फ्लोट हो, तो दूसरा फ्लोट में परिवर्तित हो जाएगा।
  • अन्यथा, अभिन्न प्रचार (4.5) दोनों ऑपरेटरों पर किया जाएगा। तो निम्नलिखित नियम पदोन्नत ऑपरेंड के लिए लागू किया जाएगा:
    • दोनों ऑपरेंड एक ही प्रकार है, तो आगे कोई रूपांतरण की जरूरत है।
    • अन्यथा, यदि दोनों ऑपरेटरों ने पूर्णांक प्रकारों पर हस्ताक्षर किए हैं या दोनों में निरंतर पूर्णांक प्रकार हैं, तो कम पूर्णांक रूपांतरण रैंक के प्रकार के साथ ऑपरेंड को अधिक रैंक वाले ऑपरेंड के प्रकार में परिवर्तित किया जाएगा।
    • अन्यथा, यदि ऑपरेंड जो पूर्णांक प्रकार के हस्ताक्षर किए गए हैं, तो अन्य ऑपरेंड के प्रकार के रैंक से अधिक या बराबर रैंक होता है, हस्ताक्षरित पूर्णांक प्रकार वाले ऑपरेंड को बिना हस्ताक्षरित पूर्णांक प्रकार के ऑपरेंड के प्रकार में परिवर्तित किया जाएगा।
    • अन्यथा, यदि हस्ताक्षरित पूर्णांक प्रकार वाले ऑपरेंड का प्रकार अप्रमाणित पूर्णांक प्रकार के साथ ऑपरेंड के प्रकार के सभी मानों का प्रतिनिधित्व कर सकता है, तो हस्ताक्षरित पूर्णांक प्रकार वाले ऑपरेंड को हस्ताक्षरित पूर्णांक के साथ ऑपरेंड के प्रकार में परिवर्तित किया जाएगा प्रकार।
    • अन्यथा, दोनों ऑपरेटरों को हस्ताक्षरित पूर्णांक प्रकार के साथ ऑपरेंड के प्रकार से संबंधित हस्ताक्षरित पूर्णांक प्रकार में परिवर्तित किया जाएगा।
+3

ओहह एक मिनट पर लटका .. दोनों मामलों में इस कोड के लिए अभिन्न प्रचार ... ओह-एर –

+0

@ लाइटनेसरेसेसिन ऑर्बिट, मैं बस देख रहा था और सोच रहा था कि क्या हुआ। शर्म, क्योंकि यह सीखने के लिए रोमांचक था। – chris

+0

इसे फिक्स्ड; मैं गलत था: पी –

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