2010-05-15 13 views
6

मैंने हाल ही में सी में एक छोटी निजी परियोजना (बीजीआर मूल्य रूपांतरण कार्यक्रम के लिए आरजीबी मूल्य) शुरू किया, और मुझे एहसास हुआ कि आरजीबी से बीजीआर में परिवर्तित होने वाला एक फ़ंक्शन न केवल रूपांतरण कर सकता है बल्कि इनवर्जन भी कर सकता है। जाहिर है इसका मतलब है कि मुझे वास्तव में दो कार्यों की आवश्यकता नहीं है rgb2bgr और bgr2rgb। हालांकि, क्या इससे कोई फर्क पड़ता है कि मै मैक्रो के बजाय फ़ंक्शन पॉइंटर का उपयोग करता हूं? उदाहरण के लिए:प्रीप्रोसेसर "मैक्रो फ़ंक्शन" बनाम फ़ंक्शन पॉइंटर - सर्वोत्तम अभ्यास?

int rgb2bgr (const int rgb); 

/* 
* Should I do this because it allows the compiler to issue 
* appropriate error messages using the proper function name, 
* not to mention possible debugging benefits? 
*/ 
int (*bgr2rgb) (const int bgr) = rgb2bgr; 

/* 
* Or should I do this since it is merely a convenience 
* and they're really the same function anyway? 
*/ 
#define bgr2rgb(bgr) (rgb2bgr (bgr)) 

मैं जरूरी निष्पादन क्षमता में बदलाव के लिए नहीं देख रहा हूँ के रूप में यह जिज्ञासा से बाहर एक व्यक्तिपरक सवाल का अधिक है। मैं इस तथ्य से अच्छी तरह से अवगत हूं कि सुरक्षा प्रकार न तो खो गया है और न ही किसी विधि का उपयोग करके प्राप्त किया गया है। क्या फ़ंक्शन पॉइंटर केवल एक सुविधा होगी या क्या अधिक व्यावहारिक लाभ प्राप्त किए जाएंगे जिनसे मुझे अनजान है?

+9

व्यक्तिगत रूप से मैं सिर्फ ऐसे नाम के साथ आउंगा जो 'int swap_rb() '; – caf

+0

@caf: दोनों अन्य उपयोगों का वर्णन करता है: निश्चित रूप से एक और शानदार विचार। यह पूरी तरह से इस मुद्दे से परहेज करता है, लेकिन यह एक तर्कसंगत ध्वनि विकल्प है। +1 – Dustin

उत्तर

6

एक और संभावना है कि दूसरा फ़ंक्शन पहले कॉल करें और संकलक को इसे अनुकूलित करने के बारे में चिंता करें (पूंछ कॉल को रेखांकित या उत्पन्न करके)।

+0

अच्छा विचार। आखिरकार, मुझे अपने अनुकूलन कंपाइलर से बेहतर कोड बनाने की कोशिश क्यों करनी चाहिए? यह वास्तव में अंतर्निहित मशीन निर्देशों को समग्र रूप से व्यवहार में नहीं बदलता है। रिकॉर्ड के लिए, मैंने वास्तव में किसी फ़ंक्शन पॉइंटर, मैक्रो या सबराउटिन का उपयोग करके किसी बाइट को सहेज नहीं लिया जो अनियंत्रित आइटमों के द्विआधारी/निष्पादन योग्य को अलग करने के बाद वास्तविक फ़ंक्शन को कॉल करता है। अंत में, कंपाइलर में केवल तीन बाइट बदल गए थे (हां, केवल तीन), जहां तक ​​ऑप्टिमाइज़ेशन चला जाता है, मैं इनलाइन असेंबली का उपयोग करके अपना कोड कम पोर्टेबल बनाने के बिना पहले से कहीं ज्यादा बेहतर नहीं कर सकता। धन्यवाद! : डी – Dustin

5

मैं मैक्रो का उपयोग करूंगा। यह अधिक आम और अधिक मूर्खतापूर्ण है, और अनुवाद इकाइयों को पार करने में कम समस्याओं में चलता है (यानी आपको मैक्रो स्थैतिक घोषित करने की चिंता करने की आवश्यकता नहीं है)।

इसके अतिरिक्त, फ़ंक्शन पॉइंटर का उपयोग करके, आप अधिकांश कंपाइलरों पर इनलाइनिंग को रोकते हैं।

अंत में, समारोह सूचक के साथ, यह संभव ग्राहकों यह करने के लिए के लिए है:

int evil(const int bgr) { /* Do something evil */ } 

bgr2rgb = evil 

ज़रूर, वे शायद नहीं इस चाहते हैं, लेकिन यह bgr2rgb नीचे के समान नाम के एक चर हो सकता है संभव है लाइन जहां यह केवल एक टाइपो लेता है ....

मैक्रो, सुरक्षित है हालांकि मैं इसे इस तरह परिभाषित करेगा - वहाँ एक समारोह की तरह यहाँ मैक्रो के लिए कोई ज़रूरत नहीं है:

#define bgr2rgb rgb2bgr 
+1

फ़ंक्शन इनलाइनिंग के नुकसान का उल्लेख करने के लिए धन्यवाद। यह निश्चित रूप से कुछ जानने लायक है! साथ ही, मैं स्पष्ट रूप से 'कॉन्स्ट'-फ़ंक्शन पॉइंटर को अर्हता प्राप्त कर सकता हूं, इसे किसी अन्य फ़ंक्शन में फिर से सौंपने से रोकता हूं। एक मैक्रो का उपयोग करने के लिए जो काम नहीं करता है, मुझे उस पर कोई लाभ नहीं दिख रहा है, हालांकि मैं निश्चित रूप से ऐसी समस्या की कल्पना कर सकता हूं जहां 'int bgr2rgb = 0;' जैसी कुछ हास्यास्पद है। सुरक्षा के मामले में, एक फ़ंक्शन-जैसे मैक्रो बेहतर होता है क्योंकि यह ऐसी समस्या से बचाता है। आखिरकार, सभी मैक्रोज़ में ऐसे अजीब नाम नहीं हैं। महान इनपुट कुल मिलाकर! मुझे उम्मीद है कि और अधिक विचारशील उत्तर हैं! – Dustin

+2

फ़ंक्शन-जैसे मैक्रो बेहतर है, क्योंकि इसका मतलब है कि आपके पास अभी भी अजीब परिणाम प्राप्त किए बिना 'bgr2rgb' नामक एक स्ट्रक्चर सदस्य हो सकता है। – caf

+0

@caf: मैं सहमत हूं, लेकिन फ़ंक्शन-जैसे मैक्रो के साथ, आप फ़ंक्शन bgr2rgb फ़ंक्शन पॉइंटर को असाइन नहीं कर सकते हैं। डस्टिन की पहली विधि का उपयोग करना बेहतर है क्योंकि यह दोनों मैक्रो समस्याओं से बचाता है। – tomlogic

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