2012-04-15 10 views
6

get_cpu_var marcro जोगूढ़ #define मैक्रो लिनक्स कर्नेल स्रोत में आई

29 #define get_cpu_var(var) (*({       \ 
30   extern int simple_identifier_##var(void);  \ 
31   preempt_disable();        \ 
32   &__get_cpu_var(var); })) 

नीचे के रूप में परिभाषित किया गया है be.I को मान रहा हूँ यह समारोह मैक्रो में से एक प्रकार है जो एक चर सूचक लौट रहा था समझ से बाहर लगता है (के आधार पर तारांकन) या यह किसी प्रकार का फ़ंक्शन पॉइंटर है। क्या मैं इसके करीब भी हूं? क्या कोई मुझे प्रबुद्ध कर सकता है? जीसीसी संकलक, जो एक सी भाव में यौगिक बयान एम्बेड करने के लिए अनुमति देता है की एक गैर मानक सुविधा -

उत्तर

15

आप उद्घाटन ({ और }) बंद करने के बीच क्या देखते एक बयान अभिव्यक्ति है। इस तरह की कथन अभिव्यक्ति का परिणाम ({}) के अंदर बहुत अंतिम अभिव्यक्ति कथन है। आपके मामले में &__get_cpu_var(var) होगा।

& ऑपरेटर __get_cpu_var(var) उप-संपीड़न के परिणामस्वरूप लागू होता है। इसका मतलब है कि __get_cpu_var एक लाभा देता है। यदि यह वास्तव में सी है, तो __get_cpu_var भी एक मैक्रो होना चाहिए, क्योंकि सी भाषा कार्यों में lvalues ​​वापस नहीं आ सकता है।

& ऑपरेटर एक सूचक (संपूर्ण कथन अभिव्यक्ति का परिणाम) उत्पन्न करता है, जिसे उपर्युक्त मैक्रो परिभाषा की शुरुआत में * ऑपरेटर द्वारा प्रस्तुत किया जाता है। तो, उपरोक्त मैक्रो अनिवार्य रूप से *&__get_cpu_var(var) अभिव्यक्ति के बराबर है।

कुछ लोग पूछ सकते हैं कि इसे *&__get_cpu_var(var) के रूप में क्यों लागू किया गया है और न केवल __get_cpu_var(var)__get_cpu_var(var) के परिणामस्वरूप lvalueness को संरक्षित करने के लिए यह किया जाता है। कथन अभिव्यक्ति का नतीजा हमेशा एक रावलू होता है, भले ही ({}) के अंदर अंतिम स्टेमेंट एक लाभा था। परिणाम की lvalueness को संरक्षित करने के लिए प्रसिद्ध *& चाल का उपयोग किया जाता है।

यह चाल किसी भी तरह से जीसीसी स्टेटमेंट एक्सप्रेशन तक ही सीमित नहीं है। यह अपेक्षाकृत अक्सर सामान्य दैनिक सी प्रोग्रामिंग में प्रयोग किया जाता है। उदाहरण के लिए, मान लें कि दो चर

int a, b; 

है और आप एक अभिव्यक्ति है कि या तो a या b वापसी होगी एक lvalue के रूप में लिखना चाहते हैं चयनकर्ता चर select पर निर्भर करता है (मान लीजिए कि हम यह करने के लिए 42 प्रदान करना चाहते हैं हैं)। एक अनुभवहीन प्रयास के रूप में

(select ? a : b) = 42; 

यह इस प्रकार से काम नहीं चलेगा, क्योंकि सी भाषा में ?: ऑपरेटर अपनी ऑपरेंड के lvalueness खो देता है लग सकता है। परिणाम एक रैल्यू है, जिसे असाइन नहीं किया जा सकता है। इस स्थिति में *& चाल बचाव

*(select ? &a : &b) = 42; 

की बात आती है और अब यह अपेक्षित तरीके से काम।

यह वास्तव में कैसे है और मूल पोस्टर की मैक्रो परिभाषा में * और & का एक अनावश्यक अनावश्यक अनुप्रयोग शामिल है।क्योंकि इस बात का आप ऊपर get_cpu_var मैक्रो दोनों तरफ एक assgnment

something = get_cpu_var(something); 
get_cpu_var(something) = something; 

की है कि चाल के बिना उपयोग कर सकते हैं आप केवल दाएँ हाथ की ओर पर get_cpu_var उपयोग करने में सक्षम होगा।

सी ++ भाषा में संदर्भ का उपयोग कर एक ही प्रभाव प्राप्त किया जाता है। सी में हमारे पास कोई संदर्भ नहीं है, इसलिए हम इसके बजाए इस तरह की चाल का उपयोग करते हैं।

+0

तो * (...) परिणाम के लिए एक टाइपकास्ट है? * संपादित। नोट और धन्यवाद। –

+0

तो यह मूल रूप से '* और __get_cpu_var (var) 'देता है - लेकिन उन्होंने' __get_cpu_var (var)' को वापस क्यों नहीं किया? कुछ प्रकार की संकलन समय प्रकार की जांच? – Anthales

+1

@ एंथलेस: मैंने – AnT

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