Boost logo

Boost :

Subject: Re: [boost] [type_traits] Variadic function pointer with __fastcall calling convention
From: Stephan T. Lavavej (stl_at_[hidden])
Date: 2013-10-02 14:28:09


[Edward Diener]
> Nonetheless VC++ ( 8, 9, 10, and 11 ) does not produce a compiler error
> when a __stdcall or __fastcall calling convention is used in a pointer
> to function taking old-style varags. Do you see this as an ongoing bug
> in VC++ ?

According to my understanding, it's a "feature", not a bug (but also not a feature).

This is vaguely similar to how C++ immediately rewrites array parameters in functions to pointer parameters (and function parameters to function pointer parameters, and drops const on value parameters as far as outside callers are concerned). Different syntax results in the same type being emitted.

> If so Boost type_traits should not support it AFAICS.

There is nothing to support, because the types are identical as far as templates are concerned:

C:\Temp>type meow.cpp
#include <iostream>
#include <type_traits>
using namespace std;

int main() {
    cout << boolalpha;
    cout << is_same<void (*)(int, ...), void (*)(int, ...)>::value << endl;
    cout << is_same<void (*)(int, ...), void (__cdecl *)(int, ...)>::value << endl;
    cout << is_same<void (*)(int, ...), void (__stdcall *)(int, ...)>::value << endl;
    cout << is_same<void (*)(int, ...), void (__fastcall *)(int, ...)>::value << endl;
}

C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp
meow.cpp

C:\Temp>meow
true
true
true
true

> The list is appreciated. But were old-style varargs included in your tests ?

Yes. As I noted, they are an exception - when I specialize our type traits for old-style varargs, I don't apply any explicit calling convention, because I was unable to find anything that made the types physically different.

> I have not tried VC in VS2013, but the matter should be cleared up so
> that VC++ at least does not at accept the __fastcall calling convention
> with old-style varags if what you say in the first line of your reply is
> true.

This is not the only place where VC looks at a calling convention and decides to silently rewrite it. As I recall, VC does this for non-vararg functions on x64 too (I would have to dig up my notes to find the exact examples).

>From a library author perspective, this rewriting doesn't matter. You just want to be able to provide a set of specializations such that users (potentially saying calling conventions that get rewritten) always activate one of your specializations.

I believe I have achieved this in VC 2013 - std::is_function and std::is_member_function_pointer should always return true regardless of the user-written calling convention (with the exception of __vectorcall; I have fixed that for post-2013-RTM). Boost can achieve the exact same thing.

STL


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk