2011-06-01 16 views
15

मैं अपने खुद के कार्यों को बनाने के तरीके पर संकेतों के लिए CGPoint जैसी चीजों के लिए परिभाषाओं के आसपास पोकिंग कर रहा था लेकिन मुझे CG_INLINE का उद्देश्य पता नहीं है। दृश्यों के पीछे क्या हो रहा है?CG_INLINE क्या करता है?

CG_INLINE CGPoint 
CGPointMake(CGFloat x, CGFloat y) 
{ 
    CGPoint p; p.x = x; p.y = y; return p; 
} 

CG_INLINE CGSize 
CGSizeMake(CGFloat width, CGFloat height) 
{ 
    CGSize size; size.width = width; size.height = height; return size; 
} 

उत्तर

24

इनलाइन फ़ंक्शन कॉल कोड में संकलित किए गए हैं, फ़ंक्शन कोड के एक ब्लॉक के रूप में संकलित किए जाने के बजाय और फ़ंक्शन का उपयोग होने पर जारी किए गए कॉल निर्देशों के बजाय। देखभाल के साथ, यह थोड़ी अधिक गति और कैश हिट की अधिक संख्या प्रदान करता है। हालांकि, सी और सी ++ में inline का इतिहास चट्टानी है, इसलिए यह मैक्रो प्रभावी रूप से एक कंपाइलर स्वतंत्र static inline व्यवहार प्रदान करता है।

#if !defined(CG_INLINE) 
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 
# define CG_INLINE static inline 
# elif defined(__MWERKS__) || defined(__cplusplus) 
# define CG_INLINE static inline 
# elif defined(__GNUC__) 
# define CG_INLINE static __inline__ 
# else 
# define CG_INLINE static  
# endif 
#endif /* !defined(CG_INLINE) */ 

तो ...

  1. (इस मामले> = C99 में) एक उपयुक्त संस्करण की __STDC_VERSION__ प्रदान compilers लिए, इसका मतलब static inline (C99 इस मूल रूप की अनुमति देता है के रूप में)
  2. : परिभाषा को देखते हुए
  3. इसी तरह मेट्रोवर्क्स कोडेवायरियर या सी ++ कंपाइलर्स के लिए, जो inline मूल रूप से समर्थन करते हैं।
  4. जीसीसी के लिए सी 99 का समर्थन नहीं करने के लिए, यह static __inline__ पर हल हो जाता है। का उपयोग पिछले सी मानकों के लिए जीसीसी विशिष्ट इनलाइन विनिर्देशक है जहां इनलाइन असमर्थित है: http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Alternate-Keywords.html
  5. यदि ये सभी विफल हो जाते हैं, तो यह इनलाइन से परेशान नहीं होता है - यह केवल static है।

इन सभी परिभाषाओं से परेशान क्यों हैं? क्योंकि ऐप्पल, उनके इतिहास में, कुछ उचित कंपेलरों के माध्यम से किया गया है।पहले के दिनों में, कोडेवायरियर सी कंपाइलर उपयोगकर्ताओं के लिए पसंद का साधन था। ओएस एक्स के बाद से, ऐप्पल उद्देश्य (सी मूल रूप से संशोधक) जीसीसी के माध्यम से उद्देश्य सी और सी ++ का उपयोग कर रहा है। हाल ही में, वे झुकाव में संक्रमण कर रहे हैं। इस मैक्रो में सभी मामलों को शामिल किया गया है (और, यह देखते हुए कि नया कोर ग्राफिक्स कैसे है, मुझे संदेह है कि पुराने मैक्रो का एक संशोधित संस्करण है)।

हालांकि, कई कंपाइलर इन दिनों इनलाइन एनोटेशन को अनदेखा कर देंगे, क्योंकि उनके ऑप्टिमाइज़र प्रोग्रामर द्वारा प्रदान किए गए संकेतों से बेहतर हैं। अपने कोड में, इसके साथ परेशान न करें (मूल रूप में, या इस मैक्रो के माध्यम से) जब तक कि आप वास्तव में सुनिश्चित न हों कि आपको इसकी आवश्यकता है (और इसे प्रोफाइलिंग के माध्यम से उपयोगी साबित कर दिया है)। बेशक, आप अभी भी static चाहते हैं - उपर्युक्त सलाह inline व्यवहार को कवर करती है।

+4

+1 * * अपने कोड में, इसके साथ परेशान न करें (मूल रूप में, या इस मैक्रो के माध्यम से) जब तक कि आप वास्तव में सुनिश्चित न हों कि आपको इसकी आवश्यकता है ** (और इसे प्रोफाइलिंग के माध्यम से उपयोगी साबित कर दिया है) **। "* – DarkDust

+0

धन्यवाद। मुझे लगता है कि यह अभी भी कार्यों को परिभाषित करने के लिए उपयोगी है (विधियों के विपरीत); क्या ये सच है? – MrHen

+1

हां, फ़ंक्शन (यानी शुद्ध सी) विधियों (उद्देश्य सी विधियों) से बेहतर हो सकते हैं, जिसमें वे ओवरहेड कॉलिंग नहीं करते हैं जो कभी-कभी उद्देश्य सी संदेश के साथ अर्जित होता है। वे अन्य भाषाओं के लिए भी अधिक आसानी से बंधे होते हैं (और अन्य, शुद्ध सी/++, पुस्तकालयों में पुन: उपयोग किए जाते हैं)। –

6

CG_INLINE static inline के लिए एक #define है। यह कंपाइलर को फ़ंक्शन इनलाइन के लिए कोड बनाने का कारण बनता है, बल्कि स्टैक पर फ़ंक्शन कॉल बनाना। अधिक जानकारी के लिए here और here देखें।

7

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

वर्तमान जीसीसी के लिए, इसे static inline को हल करना चाहिए।

inline के साथ चिह्नित फ़ंक्शन का बिंदु यह है कि संकलक उस फ़ंक्शन के शरीर के समतुल्य सम्मिलित कर सकता है जहां फ़ंक्शन को कॉल किया गया था (थोड़ा अधिक महंगा) फ़ंक्शन कॉल करने के बजाय। तो अगर आप हैं:

void bar(int a, int b) 
{ 
    NSLog(@"%d", a + b); 
} 

यह एक समारोह कॉल जो कुछ आर्किटेक्चर पर महंगा हो सकता है और उदाहरण है जब के लिए बहुत ध्यान देने योग्य हो सकता है की बचत होती है:

inline int foo(int a, int b) 
{ 
    return a + b; 
} 

void bar(int a, int b) 
{ 
    NSLog(@"%d", foo(a, b)); 
} 

संकलन तो आंतरिक रूप से करने के लिए अनुमति दी है इसे करने के लिए बदलना आप फंक्शन को कुछ हज़ार बार लूप में बुला रहे हैं।

ध्यान दें कि यह केवल संकलक मतलब है इस बदलाव कर सकता है, यह जरूरी नहीं है कि यह करता करते हैं। कंपाइलर सेटिंग्स पर निर्भर करता है।

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