सी लाइब्रेरी एक ही नाम के साथ मैक्रोज़ और फ़ंक्शंस का उपयोग क्यों करती है?


20

मैं PJ प्लेंजर द्वारा 'द स्टैंडर्ड सी लाइब्रेरी' पढ़ रहा हूं जो वास्तव में दिलचस्प है। पुस्तक में बताया गया है कि न केवल पुस्तकालय का उपयोग कैसे किया जाता है बल्कि इसे कैसे लागू किया जाता है।

मैंने ctype.hअनुभाग को पढ़ना समाप्त कर दिया है और शीर्ष लेख में फ़ंक्शन को मैक्रोज़ और फ़ंक्शन दोनों के रूप में घोषित किया गया है। उदाहरण के लिए

int isdigit(int);

लेकिन

#define isdigit(c) (_Ctype[(int)(c)] & _DI)

मुझे समझ नहीं आ रहा है कि BOTH का उपयोग क्यों किया जाता है?

इसके अलावा, अगर मैं अपने स्वयं के कस्टम ctypeहेडर और कार्यान्वयन को फिर से बनाने की कोशिश करता हूं, तो मैं केवल सफलतापूर्वक संकलित कर सकता हूं यदि मैं मैक्रो हटाता हूं (परिभाषित बाहर टिप्पणी करें)।

इस पहलू को किताब में वास्तव में नहीं समझाया गया था। क्या कोई समझा सकता है?


एक कंपाइलर को मैक्रो के रूप में लागू करने के लिए मजबूर करने के लिए सी मानक में कुछ भी नहीं है। मैक्रो की संभावना पुराने दिनों के अवशेषों से होती है जब सी में इनलाइनिंग नहीं होती थी। हालांकि एक स्मार्ट कंपाइलर एक स्पष्ट इनलाइन कीवर्ड के बिना, उस फ़ंक्शन को इनलाइन करने में सक्षम होना चाहिए। तो फंक्शन की तरह मैक्रो केवल इसलिए है क्योंकि कंपाइलर को किसी ऐसे व्यक्ति द्वारा लागू किया गया था जो कंपाइलर बनाने में शानदार नहीं था।

जवाबों:


23

मैक्रो (प्रभावी रूप से) अधिक कुशल है, क्योंकि इसमें फ़ंक्शन कॉल शामिल नहीं है। इसे और अधिक आसानी से अनुकूलित किया जा सकता है, क्योंकि इसमें केवल एक संकेतक ऑफ़सेट लुकअप शामिल है।

फ़ंक्शन कॉल एक ही लाइब्रेरी के खिलाफ लिंक करने की अनुमति देता है, भले ही प्रोग्राम को मैक्रो परिभाषा के बिना संकलित किया गया हो - यदि यह एक अलग हेडर के साथ संकलित किया गया था, या सिर्फ स्रोत फ़ाइल के अंदर एक दुष्ट घोषणा के साथ। उदाहरण के लिए, आपके पास एक कंपाइलर होना चाहिए, जिसमें किसी का "बेहतर" संस्करण ctype.h हो , जिसमें मैक्रो हो, फ़ंक्शन अभी भी उपयोग के लिए रनटाइम पर मौजूद होगा।

यदि हम मानक को देखें:

7.1.4 पुस्तकालय कार्यों का उपयोग

हेडर में घोषित कोई भी फ़ंक्शन, हेडर में फ़ंक्शन-जैसे मैक्रो डे the ned के रूप में अतिरिक्त रूप से कार्यान्वित किया जा सकता है, इसलिए यदि किसी लाइब्रेरी फ़ंक्शन को स्पष्ट रूप से घोषित किया जाता है जब उसके हेडर को शामिल किया जाता है, तो नीचे दी गई तकनीकों में से एक का उपयोग घोषणा को सुनिश्चित करने के लिए नहीं किया जा सकता है। इस तरह के मैक्रो से प्रभावित। किसी फ़ंक्शन के किसी भी मैक्रो डे of नेस्ट को कोष्ठक में फ़ंक्शन के नाम को संलग्न करके स्थानीय रूप से दबाया जा सकता है, क्योंकि नाम तब बाईं कोष्ठक द्वारा पीछा नहीं किया जाता है जो मैक्रो फ़ंक्शन नाम के विस्तार को इंगित करता है। एक ही वाक्यविन्यास कारण के लिए, यह एक पुस्तकालय समारोह का पता लेने की अनुमति दी जाती है, भले ही वह मैक्रो के रूप में भी macro ned हो।

इसका मतलब है कि यदि आप लिखते हैं:

int b = (isdigit)(c);

या

int (*f)(int) = &isdigit;
int b = f(c);

तब आप वास्तविक कार्य को लागू कर रहे हैं, मैक्रो को नहीं। आप कानूनी रूप से भी लिख सकते हैं:

#undef isdigit
int b = isdigit(c);

या (स्रोत फ़ाइल में #include <ctype.h>सीधे या ट्रांसीवरली नहीं):

extern int isdigit(int);
int b = isdigit(c);

मैक्रो परिभाषा के बिना प्रोग्राम को कैसे संकलित किया जा सकता है?
user619818

extern int isdigit(int)उदाहरण के लिए @ user619818 का उपयोग करना ।
१२

बस इसलिए मैं स्पष्ट हूं, आपका मतलब है कि उपयोगकर्ता के पास कोई #include <जो कुछ भी नहीं है; लेकिन इसके बजाय int isdigit (int) जोड़ता है; कार्यान्वयन फ़ाइल के शीर्ष पर। ठीक है, बस अपनी प्रतिक्रिया के माध्यम से ठीक से पढ़ें।
user619818

एक कॉल करने योग्य फ़ंक्शन (इनलाइन मैक्रो कोड) होने से उन कार्यों के साथ अन्य भाषाओं जैसे अजगर और पर्ल को इंटरफ़ेस करने की अनुमति
मिलती है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.