|
I figured it out. Either Visual Studio builds code differently, or I've just never noticed what really happens during a function call. I even verified this in just plain Visual C++ 2005 Express, without Rhapsody.
You can call a function on a null pointer. It will execute the function that the pointer is supposed to be, even its actually null. Any access to a member attribute within this function call will fail. This is because it separates code space from data space. The code is the same for n number of objects you instantiate. So, only one copy of the code exists. Many different sets of member attributes can exist, so it keeps these copies in a separate place.
When you call a function call on a null pointer, execution will jump from the caller, to the virtual table, into the called function call code space. It executes from the only copy that ever exists. However, when you try to access a member attribute, it retrieves the address to the actual data space with the values. So, the first hop executes, or at least starts execution. However, it must read the pointer to the next hop and since the first call was null, there is no copy of data space, and no copy of the pointer. The assembly to retrieve the pointer from data space, retrieves a null instead. This is where the error occurs.
So, its not really that you try to call a function on a null pointer, that causes the problem. That actually executes. The error is because it doesn't have a handle to an object, so it can't access the pointer member attribute.
I had to step through a bunch of assembly to figure it out. To prove it, write a C++ app where ClassA calls a function on ClassB. Instantiate both classes (itsClassA and itsClassB). Add member pointer attributes in ClassA that points to an object of ClassB, but DO NOT realize the association or set the pointer. Now, call a function from ClassA onto ClassB via the uninitialized pointer to ClassB. Make sure the function call does not access any member attributes. I just printf'd some text. Even though the pointer is null, it will execute with no errors.
|