परंपरागत रूप से, सी फ़ंक्शन कॉल कॉलर के साथ कुछ पैरामीटर को स्टैक पर दबाकर, फ़ंक्शन को कॉल करने और फिर धक्का देने वाले तर्कों को साफ़ करने के लिए स्टैक को पॉप करने के साथ किए जाते हैं।
/* example of __cdecl */
push arg1
push arg2
push arg3
call function
add sp,12 // effectively "pop; pop; pop"
नोट: ऊपर दिखाया गया डिफ़ॉल्ट सम्मेलन - __cdecl के रूप में जाना जाता है।
अन्य सबसे लोकप्रिय सम्मेलन __stdcall है। इसमें पैरामीटर को फिर से कॉलर द्वारा धक्का दिया जाता है, लेकिन स्टैक को कैली द्वारा साफ़ किया जाता है। यह Win32 एपीआई फ़ंक्शंस (जैसा कि WINAPI मैक्रो इन द्वारा परिभाषित किया गया है) के लिए मानक सम्मेलन है, और इसे कभी-कभी "पास्कल" कॉलिंग सम्मेलन भी कहा जाता है।
/* example of __stdcall */
push arg1
push arg2
push arg3
call function // no stack cleanup - callee does this
यह एक छोटी सी तकनीकी विस्तार की तरह लग रहा है, लेकिन अगर वहाँ कैसे ढेर फोन करने वाले और कॉल प्राप्त करने वाला के बीच किया जाता है पर असहमति है, ढेर एक तरीका है कि बरामद होने की संभावना नहीं है में नष्ट हो जाएगा। चूंकि __stdcall क्लीनअप को ढेर करता है, इसलिए यह कार्य करने के लिए (बहुत छोटा) कोड प्रत्येक कॉलर में डुप्लीकेट होने की बजाय केवल एक स्थान पर मिलता है, क्योंकि यह __cdecl में है। यह कोड को बहुत छोटा बनाता है, हालांकि आकार प्रभाव केवल बड़े कार्यक्रमों में दिखाई देता है।
printf() जैसे वैराडिक फ़ंक्शंस __stdcall के साथ सही होने के लिए लगभग असंभव हैं, क्योंकि केवल कॉलर वास्तव में जानता है कि उन्हें साफ़ करने के लिए कितने तर्क पारित किए गए थे। कैली कुछ अच्छे अनुमान लगा सकता है (कहें, प्रारूप स्ट्रिंग को देखकर), लेकिन स्टैक क्लीनअप को फ़ंक्शन के वास्तविक तर्क द्वारा निर्धारित किया जाना चाहिए, न कि कॉलिंग-कन्वेंशन तंत्र स्वयं। इसलिए केवल __cdecl विविध कार्यों का समर्थन करता है ताकि कॉलर सफाई कर सके।
लिंकर प्रतीक नाम सजावट: ऊपर एक बुलेट बिंदु में उल्लेख किया है, "गलत" सम्मेलन के साथ एक समारोह बुला, विनाशकारी हो सकता है तो माइक्रोसॉफ्ट एक तंत्र ऐसा होने से बचने के लिए है के रूप में। यह अच्छी तरह से काम करता है, हालांकि अगर कोई नहीं जानता कि कारण क्या हैं तो यह गड़बड़ हो सकता है। उन्होंने कॉलिंग कन्वेंशन को निम्न-स्तरीय फ़ंक्शन नामों में अतिरिक्त वर्णों (जिसे अक्सर "सजावट" कहा जाता है) के साथ एन्कोड करके इसे हल करने के लिए चुना है, और इन्हें लिंकर द्वारा असंबंधित नाम के रूप में माना जाता है। डिफ़ॉल्ट कॉलिंग सम्मेलन __cdecl है, लेकिन प्रत्येक व्यक्ति को स्पष्ट रूप से/जी के साथ अनुरोध किया जा सकता है? संकलक के लिए पैरामीटर।
__cdecl (सीएल/गोलों का अंतर ...)
इस प्रकार के सभी फ़ंक्शन नाम एक अंडरस्कोर लगी होती हैं, और क्योंकि फोन करने वाले ढेर सेटअप और ढेर सफाई के लिए जिम्मेदार है पैरामीटर की संख्या नहीं है वास्तव में बात। कॉलर और कैली के लिए वास्तव में पारित पैरामीटर की संख्या पर भ्रमित होना संभव है, लेकिन कम से कम स्टैक अनुशासन को ठीक से बनाए रखा जाता है।
__stdcall (सीएल/Gz ...)
ये फ़ंक्शन नाम एक अंडरस्कोर के साथ उपसर्ग और पारित मापदंडों के बाइट की संख्या से अधिक के साथ @ जोड़ दिए जाते हैं। इस तंत्र से, "गलत" प्रकार, या यहां तक कि पैरामीटर की गलत संख्या के साथ फ़ंक्शन को कॉल करना संभव नहीं है।
__fastcall (सीएल/जीआर ...)
ये फ़ंक्शन नाम एक @ चिह्न के साथ शुरू और भी बहुत __stdcall की तरह, @parameter गिनती के साथ प्रत्यय कर रहे हैं।
उदाहरण:
Declaration -----------------------> decorated name
void __cdecl foo(void); -----------------------> _foo
void __cdecl foo(int a); -----------------------> _foo
void __cdecl foo(int a, int b); -----------------------> _foo
void __stdcall foo(void); -----------------------> [email protected]
void __stdcall foo(int a); -----------------------> [email protected]
void __stdcall foo(int a, int b); -----------------------> [email protected]
void __fastcall foo(void); -----------------------> @[email protected]
void __fastcall foo(int a); -----------------------> @[email protected]
void __fastcall foo(int a, int b); -----------------------> @[email protected]
'__stdcall' और' __cdecl' केवल वापसी (और सजावट) के बाद सफाई के लिए ज़िम्मेदारी में भिन्नता है। तर्क दोनों गुजरने के लिए समान है (दाएं से बाएं)। आप जो वर्णन कर रहे हैं वह पास्कल कॉलिंग सम्मेलन है। – a3f