2

I wonder how pointers are compared when it comes to multiple inheritance. It seems that in some circumstance, they are equal although the address is obviously different. See the following code:

class A {
    int m_i;
};

class B {
    double m_d;
};

class C: public A, public B {
    char m_c;
};

int main() {
    C c;
    A *pa = &c;
    B *pb = &c;

    std::cout << "Address of c is: " << &c << std::endl;
    std::cout << "A type pointer to c is: " << pa << std::endl;
    std::cout << "B type pointer to c is: " << pb << std::endl;
    std::cout << "if pa == &c: " << (pa == &c) << std::endl;
    std::cout << "if pb == &c: " << (pb == &c) << std::endl;

    return 0;
}

The output is:

Address of c is: 00F6F870
A type pointer to c is: 00F6F870
B type pointer to c is: 00F6F878
if pa == &c: 1
if pb == &c: 1

There is no wonder pb is different from &c. The weird thing is (pb == &c) delivers 1. I am now confused how (pb == &c) is actually evaluated.

3
  • Why are you not surprised that B *pb = &c; produces an address different from &c? In both cases, &c is converted to B* - first time for the initialization, the second time for the comparison. Is it really a wonder that the same process repeated twice produces the same outcome? Commented Sep 5, 2016 at 1:57
  • I'm not sure how you plan to do multiple inheritance in C, so I removed the tag. Commented Sep 5, 2016 at 2:06
  • Are you surprised that 2 == 2.0 compares to true? They have to be converted to the same type to do the comparison, right? Commented Sep 5, 2016 at 2:18

3 Answers 3

3

You can only compare values that have the same type. Note, I'm ignoring the case of an overloaded operator== for the purpose of this answer.

Here, you're comparing two pointers to different classes. At this point, the compiler tries to figure out if it's possible to convert one of the pointers to the type of the other pointer.

A pointer to a subclass can be automatically converted to a pointer to its superclass. And this is what the compiler does. The end result is the same actual pointer value, and they compare equal.

Sign up to request clarification or add additional context in comments.

1 Comment

Good answer. Perhaps a nice addition would be to mention how the OP can get a different comparison result by forcing a conversion to void *.
1

This line:

std::cout << "if pb == &c: " << (pb == &c) << std::endl;

in order to compare &c with pb it has to perform a conversion so that the types of the two values match. We already know that (B*)&c results in the value that is in pb, so what actually happens here is quite simply

std::cout << "if pb == &c: " << (pb == (B*)&c) << std::endl;

which results in comparing equal values.

Comments

1
class X {
    char m_x;
};

class A {
    int m_i;
};

class B {
    double m_d;
};

class C: public X, public A, public B {
    char m_c;
};

int main() {
    C c;
    A *pa = &c;
    B *pb = &c;
    void *va = pa;
    void *vb = pb;

    std::cout << "Address of c is: " << &c << std::endl;
    std::cout << "A type pointer to c is: " << pa << std::endl;
    std::cout << "B type pointer to c is: " << pb << std::endl;
    std::cout << "void type pointer equal to pA is: " << va << std::endl;
    std::cout << "void type pointer equal to pB is: " << vb << std::endl;
    std::cout << "if pa == &c: " << (pa == &c) << std::endl;
    std::cout << "if pb == &c: " << (pb == &c) << std::endl;
    std::cout << "if va == &c: " << (&c == va) << std::endl;
    std::cout << "if vb == &c: " << (&c == vb) << std::endl;

    return 0;
}

yields the following result:

Address of c is: 0x75270a47f5f0
A type pointer to c is: 0x75270a47f5f4
B type pointer to c is: 0x75270a47f5f8
void type pointer equal to pA is: 0x75270a47f5f4
void type pointer equal to pB is: 0x75270a47f5f8
if pa == &c: 1
if pb == &c: 1
if va == &c: 0
if vb == &c: 0

The compiler converts the &c address by casting it to the same type as the pointer you compared it to. To make the point clear I displaced Class A using another class, when I then copy the addresses to void* pointers it becomes clear that the actual 'value' stored is not equal to the 'value' stored in &c.

Comments

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.