- 1. Sample code
- 2. Explanation
- 3. Conclusion
Let's take a look at a small code example when a method is called on an object that is initialized with nullptr .
Sample code
We are given the following program code.
#include <iostream> using namespace std; struct X { X* self() { cout << "call method of nullptr" << endl; if (!this) { cout << "object does not exist" << endl; return nullptr; } cout << "object exist" << endl; return this; } }; int main() { X* x = nullptr; if (x->self()) { return 0; } return 0; }
Explanation
Do you think the program will crash in this case? If not, what will be output to the console?
As a rule, the program will not crash in most cases. But this is unknown. This code is an example of undefined behavior, i.e. Undefined Behavior . The behavior of the program will be determined by the internal implementation of the compiler and will not give a guaranteed result. That is, the crash of the program and the correct execution of the program are equally correct answers.
What happens if the program functions properly?
Answer: The following message will be displayed in the console
call method of nullptr object does not exist
That is, the method will be executed as a static method, as if we were referring to a static method of the class. This is possible due to the fact that the type of the object, the signature and the implementation of the called method are known. At the same time, access to the internal class variables is not performed. And checking for this allows you to verify whether the object exists. You can also do without this check, the code will still be executed until a part of the code that requires the created object is encountered.
Conclusion
However, this code is an example of undefined behavior - Undefined Behavior . Therefore, such tricks are highly discouraged when developing software. Because even if the code works now, it may stop working in the next version of the compiler. Therefore, think a few times before writing this.