सी मानक किसी भी मानक पुस्तकालय समारोह परमिट इसके अलावा एक मैक्रो के रूप में लागू किया जाना। जैसे मेक्रो परिभाषा (N1570 खंड 7.1.4) के लिए आवश्यकताएँ हैं:
Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro. The use of #undef to remove any macro definition will also ensure that an actual function is referred to. Any inv ocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments. Likewise, those function-like macros described in the following subclauses may be invoked in an expression anywhere a function with a compatible return type could be called.
एक पुस्तकालय समारोह के लिए मैक्रो परिभाषा isalpha()
सही तर्क के लिए सही ढंग से काम करना चाहिए जैसे, लेकिन यह नहीं गलत तर्क का निदान करने के लिए आवश्यक है । चूंकि मैक्रो परिभाषा को सी मानक द्वारा स्पष्ट रूप से अनुमत किया गया है, यदि कार्यान्वयन ऐसे मैक्रो प्रदान करता है तो कोई फ़ंक्शन कॉल नहीं है, और इसलिए की अपेक्षा रखने वाले फ़ंक्शन पर char*
तर्क को पार करने की बाधा लागू नहीं होती है।
यदि कोई वास्तविक फ़ंक्शन कॉल है, तो char*
int
तर्क की अपेक्षा रखने वाले वास्तविक फ़ंक्शन के लिए char*
तर्क गुजरना एक बाधा उल्लंघन है, जिसके लिए निदान की आवश्यकता होती है। वहाँ char*
से int
करने के लिए कोई अंतर्निहित रूपांतरण है।
यहां एक छोटा प्रोग्राम है जो मुद्दे को दर्शाता है:
#include <ctype.h>
int main(void) {
char *p = "hello";
isalpha(p); // line 4, possible macro invocation
(isalpha)(p); // line 5, actual function call
#undef isalpha
isalpha(p); // line 7, actual function call
}
और यहाँ gcc -std=c11 -pedantic
साथ यह संकलन (जीसीसी 4.8.2) का परिणाम है:
c.c: In function ‘main’:
c.c:5:5: warning: passing argument 1 of ‘isalpha’ makes integer from pointer without a cast [enabled by default]
(isalpha)(p); // line 5, actual function call
^
In file included from c.c:1:0:
/usr/include/ctype.h:111:1: note: expected ‘int’ but argument is of type ‘char *’
__exctype (isalpha);
^
c.c:7:5: warning: passing argument 1 of ‘isalpha’ makes integer from pointer without a cast [enabled by default]
isalpha(p); // line 7, actual function call
^
In file included from c.c:1:0:
/usr/include/ctype.h:111:1: note: expected ‘int’ but argument is of type ‘char *’
__exctype (isalpha);
^
आन लाइन 5, कोष्ठकों के आसपास isalpha
मैक्रो विस्तार को रोकें, फ़ंक्शन को स्वयं प्रकट करें। लाइन 7 पर, वास्तविक कार्य का खुलासा किया गया है क्योंकि मैक्रो परिभाषा को हटा दिया गया है।
एक वास्तविक फ़ंक्शन कॉल निहित रूपांतरण करता है, एक कलाकार नहीं; चूंकि char*
से int
तक कोई अंतर्निहित रूपांतरण नहीं है, इसलिए संकलक एक निदान जारी करता है।(यह एक घातक चेतावनी जारी कर सकता है, लेकिन जीसीसी निहित रूपांतरणों के बारे में कुछ हद तक ढीला है, हालांकि एक चेतावनी मानक की आवश्यकताओं को पूरा करती है।) मैक्रो के साथ, रूपांतरण एक स्पष्ट कास्ट ऑपरेटर द्वारा किया जाता है, जिसे संकलक द्वारा चेतावनी नहीं दी जाती है चूक।
ध्यान दें कि, कार्यान्वयन के आधार पर, सभी तीन कॉल वास्तविक फ़ंक्शन कॉल हो सकते हैं। मानक पुस्तकालय कार्यों के लिए मैक्रो परिभाषा वैकल्पिक हैं। जीएनयू सी लाइब्रेरी isalpha
के लिए एक मैक्रो परिभाषा प्रदान करती है क्योंकि मैक्रो परिभाषा फ़ंक्शन कॉल से काफी अधिक कुशल हो सकती है (हालांकि इनलाइन फ़ंक्शन समान रूप से सक्षम हो सकता है)।
पहले टुकड़ा मुझे 'gcc' और' -Wall -std = c99 -pedantic' विकल्पों के साथ किसी भी चेतावनी नहीं देता है। वास्तव में – ouah
। क्या आप कंपाइलर, संस्करण इत्यादि पर जानकारी जोड़ सकते हैं? –
@उह यहाँ एक [स्क्रीनशॉट] (http://i.imgur.com/UghzkIz.png) है! – Kareem