अक्सर, फ़ंक्शन घोषणा प्रदान करने के अतिरिक्त, सी मानक शीर्षलेख चीजों को तेज बनाने के लिए "मास्किंग मैक्रो" प्रदान कर सकते हैं। उदाहरण के लिए, अगर मैं ctype.h
में शामिल हैं, हेडर फाइल घोषणा करेंगेक्या सी मानक के लिए कोई प्रतिबंध है जो मैक्रोज़ के रूप में कार्यान्वित किए जाने की अनुमति देता है?
int isdigit(int c);
लेकिन यह भी एक मैक्रो के साथ घोषणा मुखौटा हो सकता है। मेरा मानना है कि सी मानक के अनुसार इस एक पोर्टेबल isdigit
मैक्रो है:
#define isdigit(c) ((c) >= '0' && (c) <= '9')
बेशक
, इस मैक्रो क्योंकि यह अपरिभाषित व्यवहार का परिचय भी खतरनाक है अगर आप ऐसा करते हैं, जबकि मैक्रो परिभाषित किया गया है:
int c = 'A';
printf("%d\n", isdigit(c++));
इस कल्पित मामले में यूबी से बचने के लिए, मुझे फ़ंक्शन नाम को अभिभावकों के साथ घूमना होगा: (isdigit)(c++)
। तो, मेरा सवाल यह है: क्या कोई मानक हैडरिंग मैक्रोज़ मैक्रोज़ मैक्रोज़ को परिभाषित करने के लिए कोई प्रतिबंध है? क्या वे अपरिभाषित व्यवहार का कारण नहीं बनने की गारंटी देते हैं यदि तर्क अभिव्यक्ति के दुष्प्रभाव होते हैं, या क्या वे तकनीकी रूप से अजीब व्यवहार करने की अनुमति देते हैं जैसे कि हम ऊपर देखते हैं? सीमाएं कहां हैं?
आपने प्रस्तावित मैक्रो अनुरूप नहीं है। 'Getc()' और 'putc() 'फ़ंक्शंस के (वैकल्पिक) मैक्रो कार्यान्वयन के अपवादों के साथ, मानक फ़ंक्शन की एक मैक्रो परिभाषा एक से अधिक बार अपने किसी भी तर्क का मूल्यांकन नहीं कर सकती है। यदि आपके मैक्रो misbehaves 'isdigit (C++) 'के रूप में लागू किया गया है, लेकिन कथन अनुपालन मैक्रोज़ और फ़ंक्शन के साथ सही तरीके से काम करता है। –
क्षमा करें, "मानक मैक्रोज़" से आपका क्या मतलब है? किसी भी मामले में, जब मैंने "पोर्टेबल" कहा, तो मेरा मतलब "सभी मानक-अनुपालन सी कंपाइलरों पर अच्छी तरह से व्यवहार किया गया", जब साइड इफेक्ट्स के बिना उचित तर्क पारित किया गया। –
सी मानक बताता है कि किसी भी मानक समारोह को मैक्रो के रूप में भी लागू किया जा सकता है। लेकिन यह भी मांग करता है कि किसी भी मानक सी फ़ंक्शन के किसी भी मैक्रो कार्यान्वयन ('getc()' और 'putc()' को छोड़कर) केवल एक बार अपने तर्कों का मूल्यांकन करना चाहिए, क्योंकि मैक्रो को बिल्कुल कार्य करना चाहिए जैसे कि यह एक कार्य था। इसके अलावा, प्रत्येक कार्य को एक समारोह के रूप में घोषित और कार्यान्वित किया जाना चाहिए ताकि उसका पता लिया जा सके और काम करने के लिए सूचक के रूप में चारों ओर पारित किया जा सके। पॉल ग्रिफिथ्स ने आपको मानक से उद्धृत किया है कि यह जानकारी बहुत अधिक है। ध्यान दें कि 'setjmp() 'स्पष्ट रूप से एक मैक्रो है। –