1

I am debugging some code. Execution has arrived to this method:

void EventNotifier::notify_observers(SpEventInfo pEvent, Observable* target)
{
    std::list<Observer*>::iterator it;
    for (it = m_observers.begin(); it != m_observers.end(); ++it)
    {
        Observable* observedTarget = (*it)->target();
        bool fNotify = (observedTarget == target);
        ...

The last sentence of previous excerpt has been executed. Both variables, observedTarget and target, have the same value but boolean fNotify is false! Involved 'target' objects are using multiple inheritance and 'Observable' is one of the parents. But everything is casted to Observable, so the comparison should be just pointers of same type. In fact, the debugger shows the same value for both pointers.

I have no idea of were is the problem. Any help is greately appreciated. Thank you

Cecilio Salmeron

6
  • 1
    Try using dynamic_cast. Commented Jan 15, 2013 at 20:59
  • How do you know that target and observedTarget are the same? Have you printed them out/looked at them in the debugger? Are the objects they point to the same or the actual pointers. The former doesn't mean the latter also holds. Commented Jan 15, 2013 at 20:59
  • try to print out their addresses, if they aren't the same then they aren't the same allocated object. Commented Jan 15, 2013 at 21:01
  • Do you want to compare the pointers or the Observable objects themselves? Commented Jan 15, 2013 at 21:01
  • @Paul RuberThe code is run in a unit test. I know that both objects are the same. The debugger shows that both pointers point to the same address. Commented Jan 17, 2013 at 19:24

2 Answers 2

1

Both variables, observedTarget and target, have the same value but boolean fNotify is false!

You may like to check the code by adding a print statement:

printf("%p == %p is %d\n", observedTarget, target, int(fNotify));

Involved 'target' objects are using multiple inheritance and 'Observable' is one of the parents.

If objects may derive from Observable more than once, then you may like to compare the addresses of the complete derived objects instead. dynamic_cast<void*>(ptr) returns the address of the complete derived object referenced by ptr, hence:

bool fNotify = dynamic_cast<void*>(observedTarget) == dynamic_cast<void*>(target);
Sign up to request clarification or add additional context in comments.

1 Comment

I found the problem: before invoking this method there was a wrong cast in C style, instead of a static_cast / dynamic_cast C++ style. Fixing this solved the problem. Thank you
0

If you used the wrong kind of cast when you converted the pointers, either in the function parameter or the return value of target(), you could get a corrupted pointer. dynamic_cast is the best, and static_cast should be safe too. reinterpret_cast can cause problems, and an old C-style cast could be a reinterpret_cast depending on how it's used. If you didn't use an explicit cast then that should be OK too, the automatic conversions will always be safe.

It's surprising when you first discover that casting a pointer to a different type in the inheritance tree can change the pointer value.

1 Comment

Thank you. You were right. The problem was that before invoking this method there was a wrong cast in C style, instead of a static_cast / dynamic_cast C++ style. Fixing this solved the problem. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.