it's not because of a limitation in C.
C most definitely has the limitation which C++ tried to address and failed. Return should have been a pointer to the address where the returned value ends up being copied when it's popped off the stack. Instead it's just a syntactic premature end of a function. Had it been a simple pointer to the place where the function's return value ends up being copied, C++ would not have been invented because it would have been unnecessary. I am talking about the semantic that is present in Matlab functions (where you can assign to the return value directly). C++ tried to address it by having "this" pointer, but it ended up mixing the data and the functions which operate on it. Which is why its syntax will never be simple.
int a = f();
should allow f to assign directly to the memory location where 'a' is. Like I said, there are obvious work arounds. You can pass the address of a to f() instead of doing direct assignment. But it break the semantics. And it reduces readability. And human time is more important than computer time, so readability is more important than slight loss of efficiency in execution.
The problem is that once 'a' is not an int anymore, but is a complicated structure, you are stuck. And if you still don't think that's a problem, try implementing a fully-efficient (no redundant copying or inquiries) discriminated union in either C or C++. Good luck! Your easiest solution at that point is to just generate the code in some text generating language. But if each function had access to the point of return, it would be trivial. Oh, and discriminated unions are all of networking and all of data management.