Possible Duplicate:
When does invoking a member function on a null instance result in undefined behavior?
C++ standard: dereferencing NULL pointer to get a reference?
Say I have the class:
class A
{
public:
void foo() { cout << "foo"; }
};
and call foo like so:
A* a = NULL;
a->foo();
I suspect this invokes undefined behavior, since it's equivalent to (*a).foo()
(or is it?), and dereferencing a NULL
is UB, but I can't find the reference. Can anyone help me out? Or is it defined?
No, the function is not virtual
. No, I'm not accessing any members.
EDIT: I voted to close this question but will not delete it as I couldn't find the duplicate myself, and I suspect this title might be easier to find by others.
I'm looking for the reference that says
a->x
is equivalent to(*a).x
.
Here it is:
[C++11: 5.2.5/2]:
For the first option (dot) the first expression shall have complete class type. For the second option (arrow) the first expression shall have pointer to complete class type. The expressionE1->E2
is converted to the equivalent form(*(E1)).E2
; the remainder of 5.2.5 will address only the first option (dot). In either case, the id-expression shall name a member of the class or of one of its base classes. [ Note: because the name of a class is inserted in its class scope (Clause 9), the name of a class is also considered a nested member of that class. —end note ] [ Note: 3.4.5 describes how names are looked up after the.
and->
operators. —end note ]
There is no direct quotation for dereferencing a NULL pointer being UB, unfortunately. You may find more under this question: When does invoking a member function on a null instance result in undefined behavior?
I'm aware of at least one case where this idiom is not only allowed but relied upon: Microsoft's MFC class CWnd provides a member function GetSafeHwnd which tests if this==NULL
and returns without accessing any member variables.
Of course there are plenty of people who would claim that MFC is a very bad example.
Regardless of whether the behavior is undefined or not, in practice it's not likely to behave badly. The compiler will treat a->foo()
as A::foo(a)
which does not do a dereference at the call site, as long as foo
is not virtual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With