Search code examples
c++classobjectthismember-functions

Explicitly passing *this in C++


While reading about *this, I saw:

When a nonstatic member function is called for an object, the compiler passes the object's address to the function as a hidden argument.

Then I tried:

#include <iostream>

class MyClass
{
    int myVar;
public:
    MyClass(const int& val) : myVar{val} {}
    // int getVar(MyClass* this) <-- Error: expected ',' or '...' before 'this'
    int getVar()
    {
        return this->myVar;
    }
};

int main()
{
    MyClass obj(22);
    // std::cout << obj.getVar(&obj);      <-- Error: no matching function
    // std::cout << MyClass::getVar(&obj); <-- Error: no matching function
    std::cout << obj.getVar();
    return 0;
}

Why am I not able to access the hidden argument? Is it called 'hidden' because of that?

Are only compilers allowed to do this? Can't we explicitly mention *this in the function signature?

The closest answer I've found before asking this is this. But I tried that way and still got the error. Could I get an explanation of those error messages? Because, if the compiler actually modifies those function signatures to contain *this then that should have worked, isn't it?


Solution

  • Are only compilers allowed to do this?

    Precisely. That's why it's called hidden: It's something that the compiler does on your behalf, but which is hidden from the C++ code that uses it.

    The compiler must pass the this pointer to the member function somehow, but it does not need to tell you how it does it. It could compile the code to the equivalent of MyClass::getVar(&obj), passing the this pointer in the same way that it would pass the argument for the C function free(foo). Or it might use a different mechanism that is totally incompatible with non-member argument passing. What it does under the hood is defined by the platform's Abstract Binary Interface standard (ABI), which is not part of the C++ language standard. What happens under Windows could be vastly different from what happens under Linux, and Linux on ARM could be different from Linux on X86, etc.

    That said, you can take a look at what actually happens by telling your compiler to produce the assembly code. For gcc, the incantation would be

    g++ -S -Os interestingCode.cpp
    

    This will produce a .s file that contains how g++ actually translated your code.