c++winapivisual-c++unique-ptrstdcall

Do I need `__stdcall` in `std::unique_ptr` deleter?


I want to manage a WinAPI function pair via std::unique_ptr:

#include <memory>

int* __stdcall construct(){ return new int{5}; }
void __stdcall destruct(int* v){ delete v; }

int main() {
    using Ptr = std::unique_ptr<int, void(&)(int*)>;
    Ptr v(construct(), destruct);
}

When I build a 64-bit binary with MSVC 19.33, the code works. If I build a 32-bit binary, then there is an error.

example.cpp
<source>(8): error C2660: 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr': function does not take 2 arguments
C:/data/msvc/14.33.31631/include\memory(3291): note: see declaration of 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr'
Compiler returned: 2

It works with both if I explicitly name the __stdcall in std::unique_ptr<int, void(__stdcall&)(int*)>, so I assume it is part of the function signature.

Why is there this difference in 32 and 64 bit? Is this a bug in the compiler?


Solution

  • By MS Documentation

    On ARM and x64 processors, __stdcall is accepted and ignored by the compiler; on ARM and x64 architectures, by convention, arguments are passed in registers when possible, and subsequent arguments are passed on the stack.

    So __stdcall is ignored by the 64-bit compiler but meaningful only for the 32-bit compiler.