2012-07-03 12 views
9

निम्नलिखित कार्यक्रम अपरिभाषित है व्यवहार:gcc -Wformat क्यों एक हस्ताक्षरित int पर printf% d के बारे में चेतावनी नहीं देता है?

#include <stdio.h> 

int main(void) 
{ 
    unsigned int x = -100; // This is fine, becomes UINT_MAX - 100 
    printf("%d\n", x); // This is undefined behavior. 
    return 0; 
} 

C99 7.19.6.1p8 राज्यों% d किसी पूर्णांक तर्क की उम्मीद है।

C99 7.19.6.1p9 कहा गया है "किसी भी तर्क इसी रूपांतरण विनिर्देश के लिए सही प्रकार नहीं है, तो व्यवहार अपरिभाषित है।"

हालांकि, जीसीसी -Wformat (जो -Wall के साथ शामिल है) के ऊपर कार्यक्रम, क्यों के बारे में शिकायत नहीं होगा? क्या यह एक बग है, या एक जानबूझकर चूक?

जीसीसी मैनपेज से:

-Wformat 

चेक "printf" और "scanf", आदि के लिए, सुनिश्चित करें कि तर्क की आपूर्ति की प्रारूप स्ट्रिंग के लिए उपयुक्त प्रकार निर्दिष्ट करने के लिए कहता है, और है कि रूपांतरण स्वरूप में निर्दिष्ट स्ट्रिंग समझ

+2

C99 6.3.1.3p3 पर हस्ताक्षर किए परिभाषित कार्यान्वयन है अहस्ताक्षरित के रूपांतरण कहते हैं। – jxh

+0

@ user315052: कोई रूपांतरण नहीं है; 'x' (एक 'हस्ताक्षरित int' ऑब्जेक्ट) का प्रतिनिधित्व इस प्रकार व्याख्या किया गया है कि यह 'int' प्रकार का था। –

+0

@ किथ थॉम्पसन: मुझे लगता है कि C99 7.15.1.1p2, अंतिम वाक्य के कारण है, जहां यह 'va_arg' मैक्रो के माध्यम से तर्क प्रकारों को परिवर्तित करते समय हस्ताक्षरित/हस्ताक्षरित के लिए अपवाद बनाता है। – jxh

उत्तर

8

मेरा सबसे अच्छा अनुमान यह है कि चेतावनी छोड़ दी गई है क्योंकि यूबी को मूल्य द्वारा तर्कसंगत रूप से लागू किया गया है और न केवल इस प्रकार से। va_arg हस्ताक्षर को तब तक मेल नहीं कर सकता जब तक कि मूल्य हस्ताक्षरित और हस्ताक्षरित दोनों प्रकारों में प्रतिनिधित्व योग्य न हो। हालांकि, printf और दोस्तों को va_arg के संदर्भ में निर्दिष्ट नहीं किया गया है और मानक राज्यों में यूबी में किसी प्रकार का मेल नहीं खाता है, लेकिन यह शायद मानक में एक बग है। अन्यथा, printf("%x",1); यूबी का आह्वान करेगा। विषय पर मेरे सवाल देखें:

Does printf("%x",1) invoke undefined behavior?

+0

धन्यवाद। यह समझ में आता है कि 6.2.5p6 को उसी मात्रा में भंडारण का उपयोग करने के लिए int और unsigned int की आवश्यकता होती है। भले ही एक हस्ताक्षरित पर printf% d तकनीकी रूप से अपरिभाषित है, वास्तविक मुद्दों के कारण इसके लिए कोई व्यावहारिक कारण नहीं है। – Chris

+0

मानक यह नहीं कहता कि 'printf() '' 'का उपयोग करता है, लेकिन तथ्य यह है कि आप' printf() 'फ़ंक्शन में पॉइंटर का निर्माण कर सकते हैं, इसके माध्यम से कॉल किया जा सकता है तर्क-उत्तीर्ण तंत्र में कम से कम कुछ समानता । –

+3

जीसीसी 5.0 में अब ऐसी चेतावनी है: ['-फॉर्मेट-हस्ताक्षर '] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60194) (' -Wformat' द्वारा सक्षम)। – cremno

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

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