-1

When using the pointer to member operator (->*), what pointer values for the object will invoke undefined behavior?

Specifically, if the member function in question does not access any members and is not virtual are either of the following bad?

  • Null pointers
  • Pointers to objects which have already been deleted

This question is similar but discusses regular member function calls.

To illustrate with code:

#include <iostream>     
using namespace std;     

class Foo {     
public:     
  int member(int a)     
  {     
    return a+1;     
  }     
};     

typedef int (Foo::*FooMemFn)(int);     

int main(int argc, char** argv)     
{     
  FooMemFn funcPtr = &Foo::member;     
  Foo *fStar = 0;     
  Foo *fStar2 = new Foo();     
  delete fStar2;     

  int a1 = (fStar->*funcPtr)(4);  //does this invoke UB?                                                                                                                                                                                                                             
  int a2 = (fStar2->*funcPtr)(5); //what about this?                                                                                                                                                                                                                               

  cout<<"a1: "<<a1<<"  a2: "<<a2<<endl;     

  return 0;     
}

Questions about undefined behavior are questions about the C++ standard, so I am looking for specific references to sections of the C++ standard.

Community
  • 1
  • 1
Soverman
  • 1,135
  • 1
  • 9
  • 16
  • 1
    Any invalid pointer invokes UB. A null pointer is invalid, as is a deleted pointer. Same goes for an uninitialized one. – Xeo Jul 18 '12 at 03:13

1 Answers1

1
int a1 = (fStar->*funcPtr)(4);  //does this invoke UB?  
int a2 = (fStar2->*funcPtr)(5); //what about this? 

Yes. Both statements invoke UB.
Because they are equivalent to:

fStar->member(4);
fStar2->member(5);

respectively.

eckes
  • 64,417
  • 29
  • 168
  • 201
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Can you point to any language in the standard to this effect? The actual definition of ->* seems to be rather more complex than the equivalence stated. – Soverman Jul 18 '12 at 03:15
  • @Soverman, I don't have any standard reference for now. But member function pointer is meant for invoking a function with the caller object/pointer. May be function pointer may have one more indirection extra, but that doesn't change the mechanism. Calling directly or using function pointer are not exactly same, but logical equivalent. – iammilind Jul 18 '12 at 03:32
  • Another sort of logical equivalence is that a member function is just a function taking a pointer to the class as its first argument plus some syntactic sugar. But if that were actually the case then there'd be no problem here since that pointer would never actually be dereferenced. That's why I'm looking for a little more detail than is in your answer currently, ideally in the form of a standard reference. – Soverman Jul 18 '12 at 03:57
  • 1
    @Soverman: Invoking a member function (regardless of the method of invocation) on a null pointer is undefined behavior. The language for pointer to members *must* necessarily be more complex than the language for direct calls, since a member function cannot be null but a pointer to member can. Regarding your comment, member functions *are* a function that takes a pointer to an object (`this`) with some syntactic sugar, and yet the standard states that it is undefined. Note that you can get away with it in many cases (non-virtual function no access to other members) but there is no guarantee. – David Rodríguez - dribeas Jul 18 '12 at 04:11
  • @DavidRodríguez-dribeas You're absolutely right that UB is defined by the standard. I was just trying to explain why I was looking for a reference to the standard rather than iammilind's current answer. I'd also be happy with an answer of the form "if it weren't UB then it would be impossible to implement a C++ compiler because...". – Soverman Jul 18 '12 at 05:11
  • @Soverman: 3.7.3.1p4 *The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined.* And there is no exception for calling a function through a pointer to member. – David Rodríguez - dribeas Jul 18 '12 at 14:14
  • @dribeas thanks for the reference! I've added it to the answer along with a couple others that seemed relevant. – Soverman Jul 18 '12 at 17:56