Benjamin Buch
Benjamin Buch

Reputation: 6123

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?

Upvotes: 0

Views: 100

Answers (1)

&#214;&#246; Tiib
&#214;&#246; Tiib

Reputation: 11011

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.

Upvotes: 5

Related Questions