I was thrown off by something I saw in a program this morning, and I was hoping someone could explain why / how it works. A pointer to a class was created, but the pointer was never assigned a value of the address of an instance of a class, but calling methods from the pointer worked as expected. I would expect the pointer value to be pointing to a random value, and using it to execute methods would… not work as expected.
This it is completely undefined behavior. The pointer
should be been default-initialized to 0. Any uninitialized global variable belongs to the .bss segment which the startup code (.S) clears out as pretty much the first action after boot. And calling to a nullptr is undefined. By any means this should just crash. In very special circumstances when the right functions are placed at the right places (e.g. flash mapping starts at 0x0 and there’s some code there and it hits a return instruction pretty quickly), it might not crash, but that is by absolute chance.
Actually it is not so shocking as it might look at a first glance: Member functions are stored only once per class not once per instance. Thus, to call them the compiler only needs to know the type of the class instance on which the member function is called.
In your example the type of the class instances is PowerContrlClass for both, instance and pointer. So the compiler will call the correct function. Additionally, it will pass the address of your class instance via the hidden this parameter to the member functions. If you call through instance you’ll get a correct value, if you call through your pointer (which is initialized to 0) you’ll get an invalid address (0). But, as long as you don’t access member variables you don’t need the address of the class instance and everything works nicely. As soon as you try to access a member variable from your member function your example will crash of course.
You can see what happens, if you print the passed in this pointer in your member functions: