Pointer variable is declared null, but member function performs normally

Asked

Viewed 216 times

9

Below follows an example of the code I’m trying to execute.

//main.cpp

#include <iostream>

using namespace std;

class A{
public:
    A(){}
    ~A(){}
    void teste(){
        cout << "Teste" << endl;
    } 
};


int main(){
    A *pA = NULL;

    pA->teste();
    return 0;
}

//end main.cpp

Once I declare the pointer *pA as null, I expected the program to fail. However, it runs normally and displays the message "Test".

Why does the program normally run instead of throwing an error to type null Pointer Exception?

I’m using the Qt5 platform on Linux.

1 answer

9


Why do you think you should make an exception?

The pointer is needed to refer to a data structure, i.e., to a state, to data in memory. To access class behavior, that is, its methods. the pointer does not need referencing to any memory position. By type the compiler knows where is the code of methods that are independent of the instance.

The code is in a static (fixed) area in the memory and the progressively compiler, with the linker, and then the executable load by the operating system will determine the code address. Methods are always available in the application, even if you have not created a valid instance.

Still it could generate an exception within of the method if it was trying to access some state of the class. But in this case it is not, then there is no reason to error.

What you’re telling me to do is to call out the method teste() of the kind A which happens to be referenced by the variable pA but as the class has no data, nothing needs to be stored in memory for its execution. If nothing needs to be stored, you do not need to have any memory address to refer to, then a NULL falls well. And as during the execution of the method you just make access to a stream sending a literal string and the end of line, does not access any of the instance (and neither could, since it does not exist), does not need to access anything in memory, does not need a valid address in the variable.

So what happened is logical. It would be strange for an exception to be thrown. Try creating a status field in the class and access it in the teste() or directly on main() and see what happens.

In C++ there is no need and it is not recommended to create classes without status, prefer to use simple functions and if you need to organize related functions in a single logical unit use namespace. C++ is not Java.

Do not forget to read the supplement in William Bernal’s comment below on undefined behavior that is highly undesirable (the behavior, not William’s comment :) ). It is very important.

  • This was the answer I had in mind in view of the results. However, I expected that in C++ it would be possible to access the methods of a class, only through static methods when there is no defined instance (as in Java). Thanks for the explanation.

  • @Raelmendez C++ is more "flexible" in this sense. Anyway, remember that, in general, a class without data does not make much sense. At least not in C++. In Java it does, since it wants to create the illusion that everything is object oriented. Of course I understand that you’re just testing things and not putting it into production :)

  • 3

    Complementing the answer: The point is that the language will not do any kind of Runtime checking of your code. This allows it to run as fast as possible (whereas a language like java would have to add null checks to each function call (if the compiler cannot statically prove)). But note: the behavior of calling a function in a null object is undefined. In your case particular works. But in many others it may not work. Or worse: silently corrupt another unrelated part of memory. Never use indefinite behavior.

  • 2

    Just a historical note: Calling a member function that does not access the object actually works with the null object (although it is not enforced by anything). Before the establishment of the static member functions (at Cfront 2.0 in 1989) it was common to use this technique to emulate static functions. For example, Factory::create() could be replaced by ((Factory*)NULL)->create() and achieve the same practical effect. Soon it is even possible to see this "error" in extremely legacy code.

Browser other questions tagged

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