May I have a real life example where a non-static member function not accessing the object being called via a null pointer causes observable problems? [duplicate]

StackOverflow https://stackoverflow.com/questions/9191371

문제

Possible Duplicate:
When does invoking a member function on a null instance result in undefined behavior?

Anything like this:

class Class {
public:
    void Method()
    {
       //empty;
    }
};

Class* object = 0;
object->Method();

is undefined behavior in C++ because calling non-static member functions via null pointers is formally illegal. See this answer for a detailed explanation full of quotes from the C++ Standard. I'm well aware of the theoretical part and this question is not about theory and so it's not a duplicate of that question.

In all implementations I'm aware of the code above or some equivalent thereof doesn't cause any observable problems - since the member function doesn't access the object the method will be called just fine.

May I have any real-life example in which the same setup causes practical observable problems?

도움이 되었습니까?

해결책

Simple:

struct Object { void foo(); std::string s; };

void print(Object* o) {
  o->foo();
  if (o) { std::cout << o->x << "\n"; }
}

Let us say that foo does not access any non-static attribute of Object (ie, x).

The problem is that because formally o->foo() is undefined behavior if o is null, then it is obvious that o is not null. Therefore the check is redundant.

The function is thus optimized:

void print(Object* o) {
  o->foo();
  std::cout << o->x << "\n";
}

Reversing the order does not change anything:

void print(Object* o) {
  if (o) { std::cout << o->x << "\n"; }
  o->foo();
}

is still optimized:

void print(Object* o) {
  std::cout << o->x << "\n";
  o->foo();
}

Sometimes referred to as the Time Travel Clause of Undefined Behavior by some SO members.

For more information, check out Chris Lattner's serie on Undefined Behavior:

Your specific concern is addressed in 2/3.

Whether this actually fails depend on the compiler you use, the optimization passes you specify and the order in which they run.

Do you really want to depend on all that :x ?

Of course, one would argue that's it is pointless to have a function member that does not access any state of the object... so the question itself is of little value in practice (but interesting for its theoretical aspects).

다른 팁

This is UB, so what would constitute a "problem"? To be a problem, the code would have to do something other than what the standards say it should do or what we expect it to do, otherwise it's not a problem. The standards give us no idea what the code should or will do, so whatever it does isn't a problem.

You say it doesn't cause any "observable problems". Well, of course not. Whatever it did would be fine. It could fault, and that wouldn't be a "problem" because that's what the standard tells us can happen.

It is unlikely that this code produces any problems on any platform I'm aware of. It is still undefined behavior, primarily because it is an irrelevant corner case: it could be defined that under certain conditions calling a member function on a null pointer would be OK. However, what is the point? If you don't access any of the members, why make the function a non-static member function? There is no loss in leaving this undefined as there is no conceivable need to define this case and it would thus unnecessarily complicate the language.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top