__cdecl은 C 언어에서 함수 호출 규약(call convention) 중 하나로, 함수가 호출될 때 파라미터를 스택에 푸시(push)하고 반환값을 처리하는 방식을 정의합니다. 주로 Microsoft C/C++ 컴파일러나 MinGW와 같은 컴파일러에서 사용됩니다.
__cdecl의 특징
- 매개변수 순서:
- 함수에 전달되는 매개변수들이 스택에 오른쪽에서 왼쪽 순서로 푸시됩니다. 즉, 마지막 매개변수부터 먼저 스택에 올라가고, 첫 번째 매개변수는 마지막에 올라갑니다.
- 호출자에 의한 스택 정리:
- __cdecl 규약에서 중요한 점은 호출한 함수가 매개변수를 스택에서 제거하는 책임이 있다는 것입니다. 즉, 함수 호출이 끝난 후, 호출자는 함수가 종료된 뒤 스택을 정리합니다. 이는 스택 정리 방식이 함수 내부에서 처리되는 다른 호출 규약(예: __stdcall, __fastcall)과의 차이점입니다.
- 가변 인자 함수 지원:
- __cdecl은 가변 인자 함수(예: printf, scanf)를 지원합니다. 함수에서 전달받는 인자의 개수와 타입을 함수가 직접 처리할 수 있습니다. 이는 매개변수의 개수나 타입이 미리 정해지지 않은 경우에 유용합니다.
- 함수 반환 값 처리:
- __cdecl 규약에서는 함수가 반환 값을 EAX 레지스터에 반환합니다. 이 규약에서는 함수 반환 후 호출자가 반환 값을 받아서 처리할 수 있습니다.
__cdecl과 다른 호출 규약 비교
- __stdcall:
- __stdcall은 호출된 함수가 매개변수를 스택에서 제거합니다. 따라서, __cdecl과는 다르게 호출자가 아니라 함수 자체가 스택 정리를 담당합니다.
- __stdcall은 주로 윈도우 API 함수에서 사용되며, 가변 인자 함수는 지원하지 않습니다.
- __fastcall:
- __fastcall은 인수 중 일부를 레지스터에 저장하여 처리 속도를 개선합니다. __cdecl과는 달리, 이 규약은 일부 인수를 레지스터로 처리하고, 나머지 인수는 스택에 전달합니다.
- thiscall:
- thiscall은 C++ 클래스 메서드에서 사용되며, this 포인터를 첫 번째 매개변수로 전달하는 규약입니다. 다른 매개변수는 __cdecl과 비슷하게 처리됩니다.
__cdecl 사용 예시
#include <stdio.h>
void __cdecl example_function(int a, int b)
{
printf("a: %d, b: %d\n", a, b);
}
int main()
{
example_function(1, 2);
return 0;
}
위 예시에서 example_function 함수는 __cdecl 호출 규약을 사용하고 있습니다. 호출자가 이 함수의 매개변수들을 스택에 푸시하고, 함수가 반환되면 호출자가 스택을 정리합니다.
왜 __cdecl을 사용할까?
- 호환성: __cdecl은 많은 기존 C/C++ 코드에서 기본 호출 규약으로 사용되므로 다양한 시스템에서의 호환성을 위해 자주 사용됩니다.
- 가변 인자 함수 지원: __cdecl은 printf와 같은 가변 인자 함수를 처리할 수 있는 유일한 호출 규약입니다.
- 성능: __cdecl은 호출자에 의한 스택 정리를 요구하기 때문에, 스택 사용 방식이나 함수 호출 시 약간의 성능 차이가 있을 수 있습니다. 그러나 이는 호출 규약의 특징일 뿐, 대부분의 경우 성능에 큰 영향을 미치지 않습니다.
결론
__cdecl은 함수 호출 시 매개변수를 스택에 푸시하고, 호출자가 스택을 정리하는 방식의 C 호출 규약입니다. 가변 인자 함수와 호환되며, 다양한 시스템에서 널리 사용됩니다. 다른 호출 규약들과 비교할 때, 호출자가 스택을 정리하는 방식으로 차별화됩니다.
'C++' 카테고리의 다른 글
OpenMP 란 (0) | 2024.12.10 |
---|---|
ZeroMQ 란 (0) | 2024.12.10 |
Chrono 라이브러리 기본 시간 측정 (0) | 2024.12.09 |
콘솔 컬러로 출력하도록 하는 함수 (1) | 2024.12.09 |
MSVC 자주 사용하는 단축키 모음 (1) | 2024.12.09 |