Whats the purpose of the __thiscall keyword?

Viewed 2238

When reading through the calling conventions there is a thiscall convention which purpose is pretty clear.

I understand that thiscall defines a function which is part of a class, because these functions require an object as their first hidden parameter for non-static functions.

So if I understand it right, then the following function have to be thiscall. The keyword doesn't need to be used because the compiler doesn't have much choice there and have to declare it as such.

 class Foo
 {
     public:
     int function(void) { return 1; }
 };

Now when I declare functions outside a class like this:

int __thiscall Otherfunction(void) { return 1; }
int __thiscall Otherfunction(Foo *t) { return 1; }

Then I get the compiler error:

error C3865: '__thiscall': can only be used on native member functions

It even makes sense because how would you call these functions? So why does this keyword even exist if it can not be used? Or is there some usecase where this can/has to be used?

3 Answers

these functions require an object as their first hidden parameter for non-static functions

Ironically, you half answered yourself, because what you describe here is called fastcall, not thiscall, an ancient alternative to call member functions. thiscall stores this in a register, not on the stack.

So that's your answer, not because thiscall can be used on non-member functions, but because you can use different conventions on member functions (fastcall and of course nakedcall or whatever it's called).

From the official __thiscall documentation.

On ARM, ARM64, and x64 machines, __thiscall is accepted and ignored by the compiler. That's because they use a register-based calling convention by default.

One reason to use __thiscall is in classes whose member functions use __clrcall by default. In that case, you can use __thiscall to make individual member functions callable from native code.

When compiling with /clr:pure, all functions and function pointers are __clrcall unless specified otherwise. The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.

This appears to imply that __thiscall is never required to be explicitly specified when writing plain C++ (unmanaged) code on ARM[64] or x86, or C++/CLI code in VC++ versions 2017 and later.

As I found out because of the answers, the usecase where __fastcall makes sense is, when the default calling convention has been overriden by a compiler option and you need to have a function using the specific calling convention:

class Foo
{
 public:
    int __fastcall function(void) { return 1; }
};
Related