2011-09-11 11 views
7

मैं उत्सुक हूँ जब इस फ़ाइल संकलन क्यों जीसीसी मुझे दो समान चेतावनी दिखाता है:जीसीसी खराब प्रिंटफ प्रारूप विनिर्देशक के लिए डुप्लिकेट चेतावनी क्यों दिखाता है?

$ clang test.c 
test.c:6:14: warning: conversion specifies type 'int' but the argument has type 'long' [-Wformat] 
    printf("%i\n", foo); 
      ~^  ~~~ 
      %ld 
test.c:6:14: warning: conversion specifies type 'int' but the argument has type 'long' [-Wformat] 
    printf("%i\n", foo); 
      ~^  ~~~ 
      %ld 
2 warnings generated. 

कोई भी विचार:

$ cat test.c 
#include <stdio.h> 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    printf("%i\n", foo); 

    return 0; 
} 
$ gcc-4.2 -Wall test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

दिलचस्प बात यह है बजना भी दो चेतावनी देता है?


जानकारी के लिए:

$ gcc-4.2 -v 
Using built-in specs. 
Target: i686-apple-darwin11 
Configured with: /private/var/tmp/gcc/gcc-5666.3~278/src/configure 
--disable-checking --enable-werror --prefix=/usr --mandir=/share/man 
--enable-languages=c,objc,c++,obj-c++ 
--program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib 
--build=i686-apple-darwin11 --program-prefix=i686-apple-darwin11- 
--host=x86_64-apple-darwin11 --target=i686-apple-darwin11 
--with-gxx-include-dir=/include/c++/4.2.1 
Thread model: posix 
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3) 

$ clang -v 
Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn) 
Target: x86_64-apple-darwin11.1.0 
Thread model: posix 

संपादित करें: 'बहु वास्तुकला' परिकल्पना में कुछ सुझाव दिया है अच्छा लग रहा था, लेकिन मुझे यकीन है कि यह सही है नहीं कर रहा हूँ। अगर मैं -arch के साथ एक एकल आर्किटेक्चर को मजबूर करता हूं, तो मुझे दो चेतावनियां मिलती हैं। अगर मैं -arch x86_64 -arch i386 निर्दिष्ट करता हूं, तो मुझे डुप्लिकेट चेतावनियों के दो सेट मिलते हैं!

$ gcc-4.2 -Wall -arch x86_64 test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

$ gcc-4.2 -Wall -arch x86_64 -arch i386 test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

संपादित करें: मैं सब चेतावनी प्रकार के लिए ड्यूप्स नहीं मिलता है। -Wformat एकमात्र ऐसा है जिसे मैंने अभी तक पार किया है।

$ cat test.c 
#include <stdio.h> 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    long bar; 
    printf("%i\n", foo); 

    return 0; 
} 

$ gcc-4.2 -Wall test.c 
test.c: In function ‘main’: 
test.c:7: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:7: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: unused variable ‘bar’ 
+2

Fwiw, मैं केवल एक ही त्रुटि संदेश जब मैं जीसीसी 4.1.2 का उपयोग मिलता है । क्या आप वाकई अपने निर्माण प्रणाली का आर्टिफैक्ट नहीं हैं, जो किसी भी तरह से जीसीसी को दो बार आमंत्रित कर रहा है? –

+0

धन्यवाद ओली। मुझे यकीन नहीं है, शायद यह है।: -/ –

+0

मुझे डुप्लिकेट चेतावनी नहीं दिखाई दे रहा है। लेकिन फिर, यह एक चेतावनी है कि आपको वैसे भी ठीक करना चाहिए, इसलिए ... –

उत्तर

8

इसका कारण यह है एप्पल के stdio.h हैडर printf() की अपनी घोषणा करने के लिए एक GCC format attribute देता है ...

(जैसे printf()here की घोषणा और __printflike() मैक्रो here की घोषणा देखें)

... लेकिन जीसीसी (और क्लैंग, यह बहुत जीसीसी-संगत होने की कोशिश कर रहा है!) पहले से ही अंतर्निहित ज्ञान है कि printf() एक ऐसा फ़ंक्शन है जो printf-स्टाइल तर्क लेता है। अंतर्निहित ज्ञान के कारण आपको एक चेतावनी मिल रही है, और स्पष्ट विशेषता के कारण दूसरी चेतावनी है।

आप एक ही बात अपने आप को ऐसा करने से (जीसीसी के कम से कम कई संस्करणों के साथ) दूसरे प्लेटफार्म पर समान व्यवहार प्रदर्शित कर सकते हैं:

extern int printf(const char *, ...) __attribute__((__format__ (__printf__, 1, 2))); 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    printf("%i\n", foo); 

    return 0; 
} 
+0

शानदार! समस्या सुलझ गयी। (आप यह भी दिखा सकते हैं कि '/__r/include/stdio.h' में' printf' की परिभाषा से '__DARWIN_LDBL_COMPAT (printf) __printflike (1, 2)' को हटाकर फिर से संकलन करना सही जवाब है।) –

2

ऐसा लगता है कि आप iOS के लिए संकलित कर रहे हैं: उदाहरण के लिए, अगर मैं एक अप्रयुक्त चर में फेंक मैं केवल उस के लिए एक चेतावनी मिलती है। कई आर्किटेक्चर के लिए कोड कई बार संकलित किया जा रहा है। प्रत्येक वास्तुकला के लिए चेतावनी उत्पन्न हो रही है।

+1

बहु-वास्तुकला स्पष्टीकरण समझ में आता है, लेकिन यह सुनिश्चित नहीं है कि यह मामला यहां है। अगर मैं उदा। मेरे जीसीसी या क्लैंग झंडे के लिए '-arch x86_64', मुझे अभी भी डुप्लिकेट चेतावनियां मिलती हैं। अगर मैं '-arch x86_64 -arch i386' जोड़ता हूं, तो मुझे चार चेतावनियां मिलती हैं। :) –

+1

-1: स्पष्ट रूप से वह आईओएस के लिए संकलित नहीं कर रहा है, न ही बहु-आर्क निर्माण कर रहा है। संकलक आमंत्रण प्रश्न में निर्दिष्ट है। –

3

यदि आप दो सीपीयू आर्किटेक्चर (उदाहरण के लिए आईओएम पर एआरएमवी 6/एआरएमवी 7, या मैक पर i386/x86_64) को लक्षित कर रहे हैं, तो आपको प्रत्येक चेतावनी की दो प्रतियां दिखाई देगी क्योंकि संकलक प्रत्येक फ़ाइल के लिए दो बार चलाता है (एक बार प्रत्येक आर्किटेक्चर।)

मैक पर, यदि आप पीपीसी/पीपीसी 64 समर्थन सक्षम करते हैं तो आप इसे प्रति पंक्ति 4 चेतावनियां प्राप्त कर सकते हैं। ;)

संपादित करें: मैथ्यू को इसे स्वीकृत उत्तर में स्पॉट-ऑन मिला।

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

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