stdcall and cdecl

后端 未结 9 869
旧时难觅i
旧时难觅i 2020-11-27 09:17

There are (among others) two types of calling conventions - stdcall and cdecl. I have few questions on them:

  1. When a cdecl fun
9条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-27 09:50

    Raymond Chen gives a nice overview of what __stdcall and __cdecl does.

    (1) The caller "knows" to clean up the stack after calling a function because the compiler knows the calling convention of that function and generates the necessary code.

    void __stdcall StdcallFunc() {}
    
    void __cdecl CdeclFunc()
    {
        // The compiler knows that StdcallFunc() uses the __stdcall
        // convention at this point, so it generates the proper binary
        // for stack cleanup.
        StdcallFunc();
    }
    

    It is possible to mismatch the calling convention, like this:

    LRESULT MyWndProc(HWND hwnd, UINT msg,
        WPARAM wParam, LPARAM lParam);
    // ...
    // Compiler usually complains but there's this cast here...
    windowClass.lpfnWndProc = reinterpret_cast(&MyWndProc);
    

    So many code samples get this wrong it's not even funny. It's supposed to be like this:

    // CALLBACK is #define'd as __stdcall
    LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg
        WPARAM wParam, LPARAM lParam);
    // ...
    windowClass.lpfnWndProc = &MyWndProc;
    

    However, assuming the programmer doesn't ignore compiler errors, the compiler will generate the code needed to clean up the stack properly since it'll know the calling conventions of the functions involved.

    (2) Both ways should work. In fact, this happens quite frequently at least in code that interacts with the Windows API, because __cdecl is the default for C and C++ programs according to the Visual C++ compiler and the WinAPI functions use the __stdcall convention.

    (3) There should be no real performance difference between the two.

提交回复
热议问题