2010-12-03 15 views
8

के साथ == ओप का उपयोग करते समय चेतावनी नहीं देता है GCC केवल कोड 1 और 3 के लिए चेतावनी क्यों देता है और नीचे दिए गए कोड में 2 नहीं?जीसीसी एक हस्ताक्षरित var और एक हस्ताक्षरित शाब्दिक

मैं -Wall और -g झंडे के साथ संकलन कर रहा हूं।

int main() { 

    unsigned int ui = 4; 
    int si = 6; 

    if (si == ui) { // Warning comparison b/w signed and unsigned 
     printf("xxxx"); 
    } 

    if (si == 2U) { // No Warning --- WHY ??? 
     printf("xxxx"); 
    } 

    if (si > 2U) { // Warning comparison b/w signed and unsigned 
     printf("xxxx"); 
    } 

    return 0; 
} 

उत्तर

4

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html:

-Wconversion अनुभाग:

abs ((int) x) और ui = (unsigned) -1 तरह स्पष्ट डाले के लिए चेतावनी न दें, या अगर मूल्य abs (2.0) में तरह रूपांतरण द्वारा नहीं बदला है।

के बाद से 2U शाब्दिक है, जीसीसी जानते हैं कि:

  • अगर si < 0, तो (unsigned) si >= 2^31, इसलिए s1 != 2U
  • यदि si > 0, तो (unsigned) sisi के समान मूल्य है, इसलिए (unsigned) si == 2U यदि और केवल si == 2 है।

अंत में, शाब्दिक 2U के साथ हस्ताक्षर किए si की तुलना 2 साथ si की तुलना के रूप में ही है, जैसे कि, si == 2U का परिणाम unsigned को si परिवर्तित करके बदल नहीं किया जाएगा।

आप के साथ तुलना 2^32-1 (4294967295U), 32-बिट अहस्ताक्षरित int, जो int में प्रदर्शनीय नहीं है में सबसे बड़ा है, तो si यह करने के लिए बराबर हो सकता है, भले ही si ही नकारात्मक है, यह नहीं हो सकता जो भी आप चाहते थे, तो -Wextra विकल्प के साथ एक चेतावनी उत्पन्न होती है।

1

संभवत: उस सीमा में स्थिरता के साथ समानता तुलना में कोई अस्पष्टता नहीं है जहां टाइप ओवरलैप के हस्ताक्षरित और हस्ताक्षरित संस्करण हैं।

अगर मैं

if (si == 2147483648U) { printf("xxxx"); }

के लिए इसे बदल मैं एक चेतावनी

के लिए
0

क्रिस धन्यवाद (वास्तव में, मैं -Wextra जोड़ने के लिए इससे पहले कि मैं चेतावनी आप सूचना मिल गया था) मिलता है आपका उत्तर। मुझे लगता है कि यह कारण की ओर जाता है। मेरा मूल विचार यह था कि यू प्रत्यय इस शाब्दिक को एक हस्ताक्षरित प्रकार के लिए प्रचारित करने का कारण बनता है, हालांकि मुझे लगता है कि यह केवल एक हस्ताक्षरित प्रकार के लिए प्रचारित है जब यह संख्या INT_MAX_32 से अधिक है जो 2147483647 है।

+0

यह वास्तव में ' प्रचारित 'को प्रचारित किया गया है, लेकिन इसमें कोई फर्क नहीं पड़ता है जब इसका मान 2^31 - 1. –

+0

@ryanli से कम है: यदि इसे हमेशा हस्ताक्षरित करने के लिए प्रोत्साहित किया जाता है तो si == 2U को चेतावनी भी फेंकनी चाहिए। 2147483647 जादुई बिंदु क्यों है, जहां केवल -वॉल ध्वज के साथ, जीसीसी को चेतावनी फेंकना शुरू करना चाहिए। मुझे लगता है कि मैं आपके प्रारंभिक उत्तर को समझ नहीं पा रहा हूं। – nisah

+0

क्योंकि '2 यू' एक शाब्दिक है, और यद्यपि 'si'' हस्ताक्षरित है, जीसीसी स्पष्ट रूप से संकलित समय पर जानता है कि' si' की तुलना सटीकता खोए बिना '2U' के मान से की जा सकती है: यदि' si' ऋणात्मक है , यह हस्ताक्षर किए जाने के बाद प्रचारित होने के बाद '2U' के बराबर नहीं है। लेकिन 2^31-1 से बड़े शाब्दिक मूल्यों के लिए, जीसीसी एक चेतावनी फेंकता है क्योंकि 'si' ऋणात्मक के बराबर हो सकता है यदि' si' ऋणात्मक है, जो नतीजे नहीं हो सकता है। और '-Wall' कुछ भी चेतावनी नहीं देता है क्योंकि मेरे उत्तर में लिंक दिखाता है। –

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