Reputation: 137
Can someone explain to me the following compiler error, which says that 'x' is an ambiguous reference?
Why can the compiler not allow this, if it knows that one of those variables is actually inaccessible?
class A {
int x; // private here
};
class B {
public:
int x; // public here
};
class C : public A, public B {
};
int main() {
C c;
c.x = 5; // here is the error
return 0;
}
Edit: For people who explain to me that private does not mean that it cannot be changed - I know that, and made this simple example below, but this is not the case I was asking about.
//
// the goal is to hack x, y values
//
#include <stdio.h>
#include <memory>
class A {
int x;
int _r;
double y;
public:
A() { x = 1; y = 0.5; _r = 0; }
void foo() { printf("x = %d, y = %lf, _r = %d\n", x, y, _r); }
};
int main() {
struct _B {
int x = 2;
double y = 1.5;
} b;
A a;
a.foo(); // gives "x = 1, y = 0.500000, _r = 0"
memcpy(&a, &b, sizeof(_B)); // where the sizeof B is eq 16 (4 for int, 4 for padding, 8 for double)
memcpy(&a, &b, sizeof(b.x) + sizeof(b.y)); // that is undefined behaviour, in this case _r is overridden
a.foo(); // gives "x = 2, y = 1.500000, _r = -858993460" (_r is just a part of floating point y value but with invalid cast)
return 0;
}
Upvotes: 5
Views: 788
Reputation: 19
The compiler checks for ambiguities at compile time. Because ambiguity checking occurs before access control or type checking, so when it has found out that there is an ambiguity the compiler is yet to know the access control assigned to those variables and hence throws an error. Hope that answers your question
Upvotes: 0
Reputation: 31475
Your C
contains two x
variables. One inherited from each parent class. So it's ambiguous whether you want to assign to the A::x
or the B::x
. Just because one isn't accessible doesn't mean that the other will be automatically selected. The compiler cannot know if you intended to try to assign to the private A::x
(which would then be a different error) or the public B::x
.
Also, as noted in comments, class C : public A,B
is not the same as class C : public A, public B
. In the first case you inherit publicly from A
but privately from B
(since private inheritance is the default for a class
unlike for struct
where the default is public inheritance). In the second case you'd inherit publicly from both base classes.
Upvotes: 4