Access null pointer is not generating error

Asked

Viewed 148 times

8

Testing the code below, I noticed a strange behavior. It’s working when it shouldn’t. The correct in my view was to give a segmentation failure and abort, but it seems that the compiler is doing some magic to fix the code.

What happens?

#include <iostream>

using namespace std;

class test{
public:
    void pa(){
    cout << "NULL????" << endl;
    }
};

int main()
{
    test * t = nullptr;
    t->pa();
    cout << "Hello world!" << endl;
    return 0;
}

It’s working properly and generating the output:

NULL????
Hello world!

The parameters for the compilation are as follows::

g++ -Weffc++ -pedantic -Wextra -Wall -std=c++11 -pg -m64 -g -fexceptions -g  -c main.cpp -o obj/Debug/main.o
g++  -o bin/Debug/teste obj/Debug/main.o  -pg -m64

1 answer

8


The methods are actually normal functions that have a hidden parameter that is a reference to the instance you are using (is the this). In the case there is no instance. No problem, the argument to be passed will be null. But the function can be called, it has nothing to stop because the function belongs to that class, the compiler knows it exists. Something like this:

void pa(test * this) {

We can understand that in the background all methods are static, what differentiates is only this hidden parameter, so they can be accessed in all circumstances (in fact virtual methods can not by there is an indirect and would have to access the vtable which somehow somehow remains a state member of the object.

The problem would occur if within the function tried to access some state member of the instance, implicitly or explicitly through the this. Then you’d need to access the data somewhere in the memory and it couldn’t be null.

It works because there is no technical impediment, but conceptually it is wrong, it is an "undefined behavior", there are no guarantees that will always work like this on all platforms, so the ideal is to avoid this type of call.

This doesn’t work anymore:

#include <iostream>
using namespace std;

class test {
    int x = 0;
public:
    void pa() {
        cout << x << "NULL????" << endl;
    }
};

int main() {
    test * t = nullptr;
    t->pa();
    cout << "Hello world!" << endl;
}

Behold nay working in the ideone. And in the repl it.. Also put on the Github for future reference.

The method is "compiled" thus:

void pa(teste *this) {
    cout << this.x << "NULL????" << endl;
}

And under the table the call would be:

pa(&t); //lembrando que t é nulo

Do you notice why the error occurs? Calling the function is not a problem, access the parameter this is.

  • Thanks, I will add a member to the class and try again, since the purpose here is to force the error I had already seen this behavior ( this as implicit parameter ) in the Lua language, nice to know that in C++ this also applies, although I find it counterintuitive

  • 4

    Take my +1 there. Boy, what a good answer! P.S.: And funny too. rs I laughed with the "See nay functioning on the ideone.". :)

  • @Luizvieira not everyone agreed with you, I took negative :(

  • This -1 deserves a -1 (by the same probable logic applied). :/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.