2013-02-07 17 views
13

एक फ़ंक्शन कॉल करते समय unsigned char स्वचालित रूप से int पर प्रचारित क्यों किया जाता है? नीचे दिए गए उदाहरण में f(int) और f(char) फ़ंक्शन है। यह अधिक तार्किक लग रहा था कि संकलक unsigned char तर्क को char पर तर्क देगा और f(char) पर कॉल करेगा क्योंकि उनके पास समान संख्या में बिट्स हैं। यह f(int) को इसके बजाए कॉल कर रहा है, भले ही इसका अर्थ अधिक बिट्स के साथ किसी प्रकार के तर्क को बढ़ावा देना है। कोई संकेतक जहां नियम परिभाषित किया गया है? मानक या कंपाइलर/मंच विशिष्ट?बिना हस्ताक्षरित चार स्वचालित रूप से फ़ंक्शन कॉल में int को प्रचारित किया जाता है, क्यों?

void f(int) 
void f(char) 
void f(int) 
+9

'हस्ताक्षरित चार' के सभी संभावित मानों को 'int' द्वारा दर्शाया जा सकता है। वे सभी को हस्ताक्षरित 'char' द्वारा प्रदर्शित नहीं किया जा सकता है। –

उत्तर

12

क्योंकि unsigned charchar द्वारा प्रतिनिधित्व नहीं किया जा सकता:

#include <iostream> 

void f(int key) 
{ 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
} 

void f(char key) 
{ 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
} 

int main(int argc, char* argv[]) 
{ 
    int a = 'a'; 
    char b = 'b'; 
    unsigned char c = 'c'; 

    f(a); 
    f(b); 
    f(c); 

    return 0; 
} 

इस उत्पादन उत्पन्न करता है। उदाहरण के लिए, यदि वे दोनों 8 बिट्स हैं, और आपके हस्ताक्षरित चार में मूल्य 255 है, जो signed char ओवरफ़्लो करता है - और हस्ताक्षर पूर्णांक ओवरफ़्लो अपरिभाषित व्यवहार को आमंत्रित करता है। वैसे भी, प्रिंट करने योग्य पात्रों आम तौर पर उम्मीद कर रहे हैं char में संग्रहीत करने के लिए किया जा और नहीं unsigned char (और सी तार, आदि प्रकार char[] और नहीं unsigned char[] के हैं)

तो int को बढ़ावा देने के मूल्यों 1 << (CHAR_BIT - 1) से अधिक का प्रतिनिधित्व करने के लिए आवश्यक है।

+2

लेकिन नीचे M3taSpl0it का उत्तर दें: चाहे 'char' हस्ताक्षरित है या हस्ताक्षरित है कार्यान्वयन निर्धारित है, इसलिए सिद्धांत में, यह कोड संकलक द्वारा व्यवहार में भिन्न होगा। –

+0

@ जैकएडली हाँ, यह होगा, लेकिन इस विशेष उदाहरण में (और अधिकांश कार्यान्वयन में) यह हस्ताक्षरित है। –

+0

दरअसल, लेकिन यह अभी भी –

-1

int और char सी और सी ++ में भिन्नता में भिन्न हैं, यदि char 0 से 255 तक है और यदि int है, तो इसकी सीमा 65535 है (int की रेंज ओएस के साथ अलग-अलग होगी)। तो कंपाइलर बस इसे int के रूप में मानते हैं।

+3

char (हस्ताक्षरित) में उल्लेखनीय है कि वास्तव में -128 से 127 तक है और यह 0 से 255 तक के हस्ताक्षर किए गए चार के समान नहीं है। – KBart

+0

तो तर्क के रूप में गुजरते समय, कंपाइलर बीच अंतर हस्ताक्षरित और हस्ताक्षरित? उदाहरण के लिए –

+1

देखें [यहां] (http://www.arm.linux.org.uk/docs/faqs/signedchar.php)। यह एआरएम पर आधारित है, लेकिन कई प्लेटफार्मों को एक ही समस्या का सामना करना चाहिए। आम तौर पर उन्हें मिश्रण करना अच्छा नहीं है। – KBart

7

मेरा मानना ​​है कि स्टैंडर्ड से सही व्युत्पत्ति नीचे पैरा, पाया जाता है खंड 13.3.3 बेस्ट व्यवहार्य कार्यों पर आधारित है, यानी यह समारोह अधिभार समाधान के लिए (बहुत जटिल) के नियमों का हिस्सा है।

(§13.3.3.2/4) मानक रूपांतरण दृश्यों रैंक के द्वारा आदेश दिया जाता है: एक सटीक मिलान एक संवर्धन है, जो एक रूपांतरण की तुलना में एक बेहतर रूपांतरण है तुलना में एक बेहतर रूपांतरण है। एक ही रैंक के साथ दो रूपांतरण दृश्यों अप्रभेद्य हैं, जब तक कि निम्न नियमों में से एक लागू होता है: [...]

परिवर्तित unsigned charint को पदोन्नति (§4.5 में परिभाषित के रूप में वर्गीकृत किया गया है, जब नीचे पढ़ने, टिप्पणी (unsigned) char एक पूर्णांक प्रकार) है कि:

§4.5 इंटीग्रल प्रोन्नति
[...]

(§4.5/2) बूल, char16_t, char32_t, या wchar_t के अलावा एक पूर्णांक प्रकार का एक प्रक्षेपण जिसका पूर्णांक रूपांतरण रैंक (4.13) int के रैंक से कम है, int int के रूप में परिवर्तित किया जा सकता है यदि int प्रतिनिधित्व कर सकता है स्रोत प्रकार के सभी मूल्य; अन्यथा, स्रोत प्रसार को बिना हस्ताक्षरित int के प्रकार के रूप में परिवर्तित किया जा सकता है।

जबकि char को unsigned char परिवर्तित पदोन्नति के रूप में वर्गीकृत नहीं किया गया है क्योंकि उनके रैंक समान हैं:

(§4.13/1) [...] चार रैंक के पद के बराबर होगा हस्ताक्षरित चार और हस्ताक्षर किए गए चार। [...]

यह अभिन्न रूपांतरण के रूप में वर्गीकृत किया जाता है (§4.7) के बजाय, और, जैसा कि ऊपर वर्णित पदोन्नति अधिभार संकल्प दौरान रूपांतरण से अधिक पसंद किया जाता है।

3

सी ++ मानक में, char को हस्ताक्षरित या हस्ताक्षरित (हालांकि आकार 1 बाइट) परिभाषित नहीं किया गया है, इसलिए यह कार्यान्वयन परिभाषित किया गया है। तो आपके कार्यान्वयन में मेरा मानना ​​है कि यह हस्ताक्षरित चार है इसलिए इसे पदोन्नत किया गया है।

+0

उत्कृष्ट बिंदु –

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