Reputation: 1370
The interviewer showed me a code like this and asked me whether it would compile, and give my reasoning. I told him very certainly that it will not compile, because 10 is a constant and you cannot assign a constant to a non-const reference (like int& b = 10 will not compile), also, _a is a temporary variable and it is also considered const, again, you cannot use non-const reference to refer a const variable.
However, after I came home to my surprise I found it compile perfectly with all possible compilers. Also, I didn't get the job. What part of my understanding went wrong?
class A {
int& a;
public:
A(int _a):a(_a) {}
};
int main() {
A a(10);
}
Upvotes: 23
Views: 1075
Reputation: 2993
There are 2 questions of this prob.
q1) whether it should compile or not?
Ans: it will compile because here a refers to _a, it's not compiler headache how _a will get data.
q2) Is it right code? I mean whether there will be any run time error or not?
Ans: This is not the right code. Here a refers to _a which is stack variable. So if you acess reference variable a using class A object, output will be unpredictable. Lets take an example as given below:
class A {
public:
int& a;
A(int _a):a(_a) {}
};
int main() {
A a(10);
A a1(11);
cout << a.a;
}
See the output.Output is unpredictable because you are trying to access the reference variable a which refers to stack variable of constructor
Upvotes: 4
Reputation: 147036
_a is a temporary variable and it is also considered const,
Wrong. In the scope of the constructor body and initializer list, it is not temporary at all. It is an lvalue and function argument- it lasts well beyond your single use to the entire function body.
Also, rvalues and const
have absolutely nothing to do with each other, except that in C++03 you cannot bind non-const references to rvalues. You can, for example, call plenty of non-const functions on rvalues just fine.
This code is directly equivalent to
int main() {
int i = 10;
int& x = i;
}
With the added fun of the lifetime issues involved with it being in a class.
Upvotes: 12
Reputation: 31609
This will bind to the stack, because function arguments can be bound to by reference. this is however not safe at all and will cause undefined behavior and stack corruption at some point.
Upvotes: 7
Reputation: 70379
there is no "assignment" of a const with this code...
The code calls the constructor which takes an int
and in turn calls the initializer of the int&
. You skipped several steps the compiler sees/takes when you assumed it meant int& b = 10
while it is more like _a = 10; int& a = _a;
. it compiles but is cerainly nothing you would want to use (binding a reference to stack which later on will lead to undefined behaviour/corruption)...
Upvotes: 27