संक्षिप्त जवाब:
आईएल में कोई "तुलना-नहीं-बराबर" निर्देश है, इसलिए सी # !=
ऑपरेटर का कोई सटीक पत्राचार नहीं है और इसका शाब्दिक अनुवाद नहीं किया जा सकता है।
हालांकि, एक "तुलना-बराबर" निर्देश है ( ceq
, ==
ऑपरेटर के लिए एक सीधा पत्राचार ), इसलिए सामान्य मामले में, x != y
इसके थोड़े लंबे समकक्ष की तरह अनुवाद किया जाता है (x == y) == false
।
है भी एक "की तुलना-अधिक से अधिक" आईएल (में शिक्षा cgt
) जो संकलक कुछ शॉर्टकट (यानी उत्पन्न कम आईएल कोड), एक होने अशक्त के खिलाफ वस्तुओं की है कि असमानता तुलना लेने के लिए अनुमति देता है, obj != null
, अनुवाद करा रूप में यदि वे थे " obj > null
"।
आइए कुछ और विस्तार में जाएं।
यदि IL में कोई "तुलना-नहीं-बराबर" निर्देश है, तो संकलक द्वारा निम्नलिखित विधि का अनुवाद कैसे किया जाएगा?
static bool IsNotEqual(int x, int y)
{
return x != y;
}
जैसा कि पहले ही ऊपर कहा, संकलक बदल जाएगी x != y
में (x == y) == false
:
.method private hidebysig static bool IsNotEqual(int32 x, int32 y) cil managed
{
ldarg.0 // x
ldarg.1 // y
ceq
ldc.i4.0 // false
ceq // (note: two comparisons in total)
ret
}
यह पता चला है कि संकलक हमेशा इस काफी लंबे-घुमावदार पैटर्न का उत्पादन नहीं करता है। आइए देखें कि जब हम y
निरंतर 0 से बदलते हैं तो क्या होता है :
static bool IsNotZero(int x)
{
return x != 0;
}
उत्पादित आईएल सामान्य मामले की तुलना में कुछ कम है:
.method private hidebysig static bool IsNotZero(int32 x) cil managed
{
ldarg.0 // x
ldc.i4.0 // 0
cgt.un // (note: just one comparison)
ret
}
कंपाइलर इस तथ्य का लाभ उठा सकता है कि हस्ताक्षर किए गए पूर्णांक दो के पूरक में संग्रहीत किए जाते हैं (जहां, यदि परिणामी बिट पैटर्न को अहस्ताक्षरित पूर्णांक के रूप में व्याख्या किया जाता है - यही .un
इसका मतलब है - 0 का सबसे छोटा संभव मूल्य है), इसलिए यह अनुवाद x == 0
करता है जैसे कि यहunchecked((uint)x) > 0
।
यह पता चलता है कि कंपाइलर असमानता की जांच के लिए सिर्फ इतना ही कर सकता है null
:
static bool IsNotNull(object obj)
{
return obj != null;
}
संकलक लगभग उसी आईएल का उत्पादन करता है जैसे IsNotZero
:
.method private hidebysig static bool IsNotNull(object obj) cil managed
{
ldarg.0
ldnull // (note: this is the only difference)
cgt.un
ret
}
जाहिरा तौर पर, कंपाइलर को यह मानने की अनुमति है कि बिट पैटर्न null
संदर्भ का बिट पैटर्न किसी भी वस्तु संदर्भ के लिए संभव सबसे छोटा बिट पैटर्न है।
यह शॉर्टकट कॉमन लैंग्वेज इन्फ्रास्ट्रक्चर एनोटेट स्टैंडर्ड (अक्टूबर 2003 से प्रथम संस्करण) में स्पष्ट रूप से उल्लेख किया गया है (पृष्ठ 491 पर, टेबल 6-4 के फुटनोट के रूप में, "बाइनरी तुलना या शाखा संचालन"):
" cgt.un
ObjectRefs (O) पर अनुमति दी गई है और पुष्टि की गई है। इसका उपयोग आमतौर पर अशक्त ऑब्जेक्ट के साथ null की तुलना करते समय किया जाता है (कोई तुलना नहीं-बराबर" निर्देश है, जो अन्यथा अधिक स्पष्ट समाधान होगा)। "
int
का वैसा ही प्रतिनिधित्व होint
जैसा वे करते हैंuint
। यह दो के पूरक की तुलना में बहुत कमजोर आवश्यकता है।