2012-10-25 10 views
13

मैं था (जल्दी से) कुछ कोड लिखने और गलती से scanf() में तर्क औंधा:उल्टा तर्क()

char i[] = "ABC1\t"; 
scanf(i, "%s"); 

gcc -Werror -Wall -Wextra साथ संकलन यह एक बिट के बारे में शिकायत नहीं है। जाहिर है, यह कोड काम नहीं करता है, लेकिन जीसीसी ने मुझे सूचित क्यों नहीं किया कि मैंने तर्कों को उलटा किया? क्या यह पता नहीं लगा सकता कि i प्रारूप स्ट्रिंग नहीं है, या दूसरा तर्क स्टोर-सक्षम प्रकार नहीं था?

संपादित
अंतर्दृष्टि सभी के लिए धन्यवाद, ऐसा लगता है कि मैं इस सवाल का जवाब मिल गया है, वहाँ है कि इस "catchable"

उत्तर

17

हा! मुझे यह मिला। -Wformat=2 ध्वज के साथ जीसीसी मारना इसे पकड़ा।

दूसरों के संदर्भ के लिए जानकारी पोस्ट करना:

यहाँ जो यह करता है list of flags I found

-Wformat Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...

मैं -Wall मान लिया था कि यह में -Wformat था है, है, लेकिन के बारे में बहुत ही महत्वपूर्ण हिस्सा है कि मैं क्या सिर्फ मिला:

-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.

+0

हाँ, +1 मैं भी इसकी तलाश कर रहा था। \ – Omkant

8

(यह संदर्भ के लिए नीचे पोस्ट) -Wformat झंडे पर एक मोड़ मैं इसे लगता था नहीं करना चाहिए।

int scanf (const char * format, ...); 

i सामान्य रूप से एक const char* में बदल दिया गया, सभी बाकी मापदंडों बस "अंडाकार" कर रहे हैं और संकलन समय पर चेक नहीं किया जा सकता है।

+1

हे जीसीसी द्वारा उपयोग किए जाने वाले डर्स में आमतौर पर पहला पैरामीटर प्रारूप स्ट्रिंग के रूप में चिह्नित होता है और फिर यह सुनिश्चित कर सकता है कि सही प्रकार शेष पैरामीटर को पास किए जाते हैं, बशर्ते '-फॉर्मैट' प्रदान किया गया हो। मेरा मानना ​​है कि यह '-वॉल' का हिस्सा है। – Will

+1

@ फिर भी - एक गैर-कॉन्स char * प्रारूप स्ट्रिंग के रूप में पारित किया गया था (जो स्वयं द्वारा मान्य है) और इसलिए कंपाइलर पैरामीटर जांच को मजबूर नहीं करता था। ऐसा हो सकता है अगर प्रारूप स्ट्रिंग 'const char *' या शाब्दिक था। – Lyth

+0

शायद यह 'char * fmt' और 'const char * fmt' के बीच जांच नहीं करता है। क्या कोई बता सकता है, अगर दूसरा तर्क ("एबीसी \ टी") char * या const char * होगा? – anishsane

3

scanf (आदमी scanf) के लिए मैनुअल प्रविष्टि प्रोटोटाइप देता है:

int scanf(const char *format, ...); 

एक चार [] तो पहले तर्क से संतुष्ट है, बस चार * एक विशेष प्रकार का है। रनटाइम पर माध्यमिक तर्कों का मूल्यांकन किया जाता है (यदि मुझे याद है), तो उन्हें यहां कंपाइलर द्वारा भी नहीं माना जाता है। कंपाइलर के संभावित से, यह प्रोटोटाइप दिए गए फ़ंक्शन के लिए एक बढ़िया कॉल है।

इसके अलावा, संकलक कभी भी जांच नहीं करता कि आप अमान्य स्थानों पर लिखने की कोशिश कर रहे हैं या नहीं। सी के बारे में महान (या भयानक) बात यह है कि यह आपको जितना चाहें उतना कम या कम करने देगा, भले ही आप जो चाहते हैं वह एक बुरा विचार है।

+2

यह सच है कि 'स्कैनएफ' स्वयं इन्हें स्वीकार करता है, लेकिन जीबीसी के साथ संकलित ग्लिब में, स्कैनफ में '__attribute __ ((प्रारूप (स्कैनफ़, 1, 2)) है) जो संकलक को यह सुनिश्चित करने के लिए बताता है कि पैरामीटर सही हैं, भले ही यह 'स्कैनएफ' की घोषणा द्वारा लागू नहीं किया गया है। – Shahbaz