CDECL तर्कों में रिवर्सल ऑर्डर में स्टैक पर धकेल दिया जाता है, कॉलर स्टैक को साफ़ करता है और परिणाम प्रोसेसर रजिस्ट्री के माध्यम से वापस आ जाता है (बाद में मैं इसे "रजिस्टर ए" कहूंगा)। STDCALL में एक अंतर है, कॉल करने वाले ने स्टैक को साफ नहीं किया है, बछड़ा करते हैं।
आप पूछ रहे हैं कि कौन सा तेज है। कोई नहीं। जब तक आप कर सकते हैं आपको देशी कॉलिंग कन्वेंशन का उपयोग करना चाहिए। अगर कोई रास्ता नहीं है, तो केवल बाहरी पुस्तकालयों का उपयोग करने के लिए, जो कुछ सम्मेलन का उपयोग करने के लिए निश्चित सम्मेलन की आवश्यकता होती है, तो सम्मेलन को बदलें।
इसके अलावा, ऐसे अन्य कन्वेंशन हैं जो कंपाइलर डिफ़ॉल्ट रूप में चुन सकते हैं यानी विजुअल C ++ कंपाइलर FASTCALL का उपयोग करता है जो कि प्रोसेसर रजिस्टरों के अधिक व्यापक उपयोग के कारण सैद्धांतिक रूप से तेज है।
आमतौर पर आपको कुछ बाहरी लाइब्रेरी को दिए गए कॉलबैक फ़ंक्शंस के लिए एक उचित कॉलिंग कन्वेंशन सिग्नेचर देना होगा यानी qsort
C लाइब्रेरी से कॉलबैक CDECL होना चाहिए (यदि डिफ़ॉल्ट रूप से कंपाइलर अन्य कन्वेंशन का उपयोग करता है तो हमें कॉलबैक को CDECL के रूप में चिह्नित करना होगा) या अन्य WinAPI कॉलबैक होना चाहिए STDCALL (संपूर्ण WinAPI STDCALL है)।
अन्य सामान्य मामला तब हो सकता है जब आप कुछ बाहरी कार्यों के लिए पॉइंटर्स स्टोर कर रहे हों अर्थात WinAPI फ़ंक्शन के लिए एक पॉइंटर बनाने के लिए इसकी प्रकार परिभाषा को STDCALL के साथ चिह्नित किया जाना चाहिए।
और नीचे एक उदाहरण दिखाया गया है कि कंपाइलर यह कैसे करता है:
i = Function(x, y, z);
int Function(int a, int b, int c) { return a + b + c; }
CDECL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call (jump to function body, after function is finished it will jump back here, the address where to jump back is in registers)
move contents of register A to 'i' variable
pop all from the stack that we have pushed (copy of x, y and z)
copy 'a' (from stack) to register A
copy 'b' (from stack) to register B
add A and B, store result in A
copy 'c' (from stack) to register B
add A and B, store result in A
jump back to caller code (a, b and c still on the stack, the result is in register A)
STDCALL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call
move contents of register A to 'i' variable
pop 'a' from stack to register A
pop 'b' from stack to register B
add A and B, store result in A
pop 'c' from stack to register B
add A and B, store result in A
jump back to caller code (a, b and c are no more on the stack, result in register A)