Right now I'm learning the ins and outs of C and C++. I know that when you create an array inside a function, then it is stored inside that function's stack frame. You can return the base address of the array, which is in fact a pointer to the first element in that array. That returned pointer value gets stored into the EAX/RAX register, and then the value from the register is then moved into a pointer variable local to the calling function. The problem is that when the function returns, that function's stack frame gets popped off the called stack, and any data declared inside that function's stack frame expires. The pointer is now pointing to an invalid memory location.
I want to be able to return an array from a called function BY VALUE, not by pointer. The array has to be created inside the function and stored on the stack. I want to return an array by value just as you would return an int that was declared inside the called function.
int f() {
int a = 5;
return a; // returned by value
}
int main() {
int b = f();
return 0;
}
Here the int value is moved into the EAX/RAX register, so it is a copy. The called function's stack frame is cleared off the call stack, but there is no problem since the returned value is now stored in the register just before copying it into int b.
I know that in C++ I can create a vector inside the called function and then return it by value. But I don't want to use such higher level abstractions in favor of learning a "hacky" way to do it. I'll come back to vectors in a bit.
Well, I realized that it is possible to return a struct object by value from a function. So my solution to returning an array by value is very simple: put it inside a struct, and return that struct by value!
struct String {
char array[20];
};
struct String f() {
struct String myString;
strcpy(myString.array, "Hello World");
return myString; // Is this returned by value?
}
int main() {
struct String word = f();
printf("%s\n", word.array);
}
Please clarify me if I understand the code correctly. That struct object gets created inside the called function's stack frame, "Hello World" is copied into the array contained within, and then what?
The struct String word
is a lvalue and f()
returns an rvlaue. When one struct is assigned to another all of it's data members are copied one by one.
What happens in between, just after the struct is returned from the called function by value, and before it is assigned to the struct inside the main()
function? The EAX/RAX register is the destination for returned values. It is either 64 bits or 32 bits depending if you have a 64 or 32-bit computer. How exactly do you fit a struct object into a register? I imagine that the array maybe not only 20 bytes, but let's say 100 bytes! Is the struct copied from the function into the register piece-by-piece? Or is it copied from one memory location on the stack to another by value all in one go? And also what happens to the original struct object which was created inside the called function? Those are all questions that I'd like to know answers to.
Also, about returning vectors from functions by value. Vectors in C++ are classes, and classes are similar to structs. Can you answer the question, what happens when you return a vector by value from a function? And what happens when you pass a class/struct object into a function as a parameter?
I can imagine how pass by value works with small data types. I don't even know how it works for complex data types and data structures.