Ardent Coder
Ardent Coder

Reputation: 3995

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?

Upvotes: 1

Views: 1976

Answers (3)

armagedescu
armagedescu

Reputation: 2160

When you are doing obj.getVar() it is already explicitly specified the pointer this=&obj and passed implicitly to getVar. It is not hidden. It is explicitly passed leftside of the function. You can use obj.getVar() or ptrObj->getVar() but in C++ is not allowed to use such construction getVar(thisptr). Hidden means the variable named this is nowhere declared, but you can use inside the function.

Upvotes: 2

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.

Upvotes: 3

James Adkison
James Adkison

Reputation: 9602

obj.getVar(&obj)

This version cannot compile because the getVar() member function is not declared to take any parameters.

MyClass::getVar(&obj)

This version is using the syntax to access a static function but getVar() is not static, nor does it accept any parameters.

Note: The obj.getVar() call works because it is specifying which object instance to use (i.e., the obj. part) to execute the member function and is conceptually how the member function is passed the this pointer.

Upvotes: 2

Related Questions