What is stack-based reference?
What is stack-based references? How are they different from references that are members of objects? Does the Standard talk about these?
I came across this in an article written by Herb Sutter:
Q1: Is the following code legal C++?
// Example 1
string f() { return "abc"; }
void g() {
const string& s = f();
cout <&l开发者_Python百科t; s << endl; // can we still use the "temporary" object?
}
A1: Yes. This is a C++ feature… the code is valid and does exactly what it appears to do.
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself, and thus avoids what would otherwise be a common dangling-reference error. In the example above, the temporary returned by f() lives until the closing curly brace. (Note this only applies to stack-based references. It doesn’t work for references that are members of objects.)
In the given context, stack-based references means a reference that is an automatic object on the stack.
That is, in
// ...
{
// ...
const foo& x = some_foo;
// ...
}
// ...
x
is a stack-based object, while the_foo
in
class bar {
// ...
foo& the_foo;
// ...
};
isn't.
A stack based reference is a reference that is the parameter of a function call or a local non-static variable inside a block. All other references are not stack based.
int foo;
static int &fooref = foo; // Not stack based.
class A {
public:
A(int &z) : x(z) {} // z is stack based, x isn't.
int &x; // Not stack based.
};
void joe(int &i) { // i is stack based.
int &k = i; // k is stack based.
static int &j = i; // j is not stack base and this will likely result in a bad error later.
A a(k); // a is stack based, but A.x still isn't.
}
A stack-based reference is the alternative to a heap-based reference. In general, return values and local variable values are allocated in the "call stack", the place that stores what the sequence of currently running functions are.
In general, when you call a function, a 'stack frame' is dropped on the stack, including enough space for all local variables, arguments and the return value of the function. While in that function, that stack frame remains alive along with all of its values; when the function terminates, the stack frame is generally discarded and you return to the next level up.
In this case, "abc" goes in the stack frame for f(), but c++ is smart enough to allocate it right next to the stack frame of the parent; when f() is popped from the stack, the stack frame for g() (which is directly below f() in the stack, since g() called f()) is adjusted to hang onto the value "abc".
This describes objects allocated on the stack; the alternative is objects in the heap, which are persistent. OBjects on the heap are managed using 'new' and 'delete', and held in place by pointers or heap references. Stack objects will automatically free when you finish with the function; objects on the heap have to be manually freed.
A stack-based reference is simply a reference that lives on the stack.
int main()
{
int a = 3;
int &b = a; // b is a stack-based reference
...
}
精彩评论