0

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?

Benjamin Buch
  • 4,752
  • 7
  • 28
  • 51
  • The [WIL](https://github.com/microsoft/wil) probably already provides what you're trying to implement here. – IInspectable Apr 24 '23 at 09:21
  • 2
    There is only one possible calling convention for x64, so the compiler just uses that always. – BoP Apr 24 '23 at 11:09
  • 1
    "*so I assume it is part of the function signature*" - yes, a calling convention is part of the signature. If no convention is specified, `__cdecl` is the default (unless the compiler is configured otherwise). But in 64-bit, there is only 1 convention available (and no keyword for it), so all other conventions (`__cdecl`, `__stdcall`, etc) are simply ignored. – Remy Lebeau Apr 24 '23 at 17:31

1 Answers1

5

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Öö Tiib
  • 10,809
  • 25
  • 44