2013-07-01 5 views
6

मैंने कोड पर ठोकर खाई जो वैध प्रतीत नहीं होता है, लेकिन जाहिर है क्योंकि यह Mono codebase for already 2 years में बैठा है। नीचे छोटा अंश है। मैक्रो "mono_atomic_load_acquire" का परिणाम unload_data_unref (..) में परिवर्तनीय "गिनती" के लिए असाइन किया जा सकता है। मुझे लगता है कि __tmp असाइन किया जा रहा है, लेकिन मुझे सी में इस तरह से स्कॉइंग का उपयोग करने की कोई जानकारी नहीं मिल सकती है। क्या कोई भी समझा सकता है या कुछ उपयोगी लिंक दें?सी वैरिएबल स्कोप ब्लॉक से रिटर्न वैल्यू के साथ असाइन किया गया है?

#define mono_atomic_load_acquire(target) ({ \ 
    typeof (*target) __tmp = *target; \ 
    LOAD_ACQUIRE_FENCE; \ 
    __tmp; }) 

#define LOAD_ACQUIRE_FENCE MEMORY_BARRIER 
#define MEMORY_BARRIER mono_memory_barrier() 

static inline void mono_memory_barrier (void) 
{ 
    // platform specific code 
} 

unload_data_unref (unload_data *data) 
{ 
    gint32 count; 
    do { 
     count = mono_atomic_load_acquire (&data->refcount); 
     g_assert (count >= 1 && count <= 2); 
     if (count == 1) { 
      g_free (data); 
      return; 
     } 
    } while (InterlockedCompareExchange (&data->refcount, count, count - 1) != count); 
} 
+0

मैं बस नहीं देखा है इसके समान कुछ भी। यह एक समारोह नहीं है, लेकिन कोड का एक ब्लॉक जहां चर के बाद चर के बाहर जाना जाता है। यह एक मूल्य कैसे वापस कर सकता है? – voldemarz

+0

यह मुझे विजुअल स्टूडियो 2012 के तहत मोनो संकलित करने से रोक रहा है। मैं इसे विजुअल स्टूडियो में कैसे लिखूं? –

उत्तर

5

यह एक जीएनयू विस्तार, वे कहा जाता है है बयान भाव (मानक सी भाषा "अभिव्यक्ति बयान" कहा जाता है निर्माण के साथ भ्रमित होने की नहीं)। वास्तव में यह __tmp है जो असाइन किया गया है। Docs here.

0

तो यह statement expression है। यह एक gcc extension और प्रलेखन 6.1 Statements and Declarations in Expressions के अनुसार है:

यौगिक बयान में आखिरी बात एक अभिव्यक्ति अर्धविराम द्वारा पालन किया जाना चाहिए; इस सबएक्सप्रेस का मूल्य पूरे निर्माण के मूल्य के रूप में कार्य करता है।

इस मामले में यह __tmp होगा। प्रलेखन के अनुसार:

यह सुविधा विशेष रूप से मैक्रो परिभाषाओं को "सुरक्षित" बनाने में उपयोगी होती है (ताकि वे प्रत्येक ऑपरेंड का सटीक मूल्यांकन कर सकें)।

यह statement expressions का उपयोग किए बिना इस उदाहरण देता है:

#define max(a,b) ((a) > (b) ? (a) : (b)) 

बनाम इस safe संस्करण, चेतावनी है कि आप ऑपरेंड के प्रकार पता के साथ:

#define maxint(a,b) \ 
    ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) 
संबंधित मुद्दे