Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does std::function know about calling convention?

int __cdecl ccall(int i)
{
    wprintf(L"ccall(%d)", i);
    return 0;
}

int __stdcall stdcall(int i)
{
    wprintf(L"stdcall(%d)", i);
    return 0;
}

int __cdecl wmain(int argc, wchar_t **argv)
{
    std::function<int(int)> fnc = ccall;
    std::function<int(int)> fnstd = stdcall;

    fnc(10); // printed well
    fnstd(100); // printed well
    return 0;
}

I was concerned how do I assign a __stdcall function to std::function object. But without any specifying calling convention, it looks like working fine. How can std::function know what calling convention is?

like image 384
Benjamin Avatar asked Apr 16 '12 07:04

Benjamin


1 Answers

std::function is able to store function pointers that use any calling convention.

§ 20.8.11.2:

The function class template provides polymorphic wrappers that generalize the notion of a function pointer. Wrappers can store, copy, and call arbitrary callable objects (20.8.1), given a call signature (20.8.1), allowing functions to be first-class objects.

As John Calsbeek added: There is nothing in particular in the standard concerning the calling conventions, but the compilers are doing their job and function pointers contain the information about the convention.

With function pointers you would need to specify the unusual calling convention:

typedef int(* c_ptr_t)(int);
typedef int(__stdcall * std_ptr_t)(int);

c_ptr_t c_ptr = ccall;
std_ptr_t std_ptr = stdcall;

// But std::function doesn't mind:
std::function<int(int)> fnc = c_ptr;
std::function<int(int)> fnstd = std_ptr;
like image 79
Anonymous Avatar answered Oct 29 '22 15:10

Anonymous