CDECL argümanları yığına ters sırayla itilir, çağıran yığını temizler ve sonuç işlemci kayıt defteri aracılığıyla döndürülür (daha sonra "kayıt A" olarak adlandıracağım). STDCALL'da bir fark vardır, arayan kişi yığını temizlemez, arama yapar.
Hangisinin daha hızlı olduğunu soruyorsunuz. Hiç kimse. Mümkün olduğu kadar yerel arama kuralını kullanmalısınız. Kuralı yalnızca bir çıkış yolu yoksa, belirli bir kuralın kullanılmasını gerektiren harici kitaplıkları kullanırken değiştirin.
Ayrıca, derleyicinin varsayılan olarak seçebileceği başka kurallar da vardır, yani Visual C ++ derleyicisi, işlemci kayıtlarının daha kapsamlı kullanımı nedeniyle teorik olarak daha hızlı olan FASTCALL kullanır.
Genellikle, bazı harici kitaplıklara iletilen geri arama işlevlerine uygun bir arama kuralı imzası vermelisiniz, yani qsort
C kitaplığından geri arama CDECL olmalıdır (derleyici varsayılan olarak başka bir kural kullanıyorsa geri aramayı CDECL olarak işaretlemeliyiz) veya çeşitli WinAPI geri aramaları STDCALL (WinAPI'nin tamamı STDCALL'dur).
Diğer olağan durumlar, bazı harici işlevlere işaretçiler depoladığınızda olabilir, yani WinAPI işlevine bir işaretçi oluşturmak için, tür tanımının STDCALL ile işaretlenmesi gerekir.
Aşağıda, derleyicinin bunu nasıl yaptığını gösteren bir örnek verilmiştir:
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)