Broken C code: followup
I received a number of comments on my previous blog post, with people stating that my example code wasn't right, either.
For reference, here's my code snippet again:
#include <stdio.h> void* f(); int main() { long* a; a=(long*)f(); printf("%Ld\n", *a); return 0; } void* f() { static long a=84; printf("%Ld\n", a); return &a; }
First, let me make one thing perfectly clear: the "a" variable is not on the stack. It is a locally-scoped variable, but it is also declared as static, meaning that it's valid for the entire run of the process; if it were on the stack, then this variable would vanish when the function would end. Yes, it's wrong to return a pointer to a variable on the stack, since there's no guarantee that the stack value will still be valid; but I'm not doing that.
Alternative implementations could've used a global variable, or could've malloc()'ed a pointer; but the compiled assembly code for my C code will only differ from a version with a global variable in the used label for the variable's location, and in the lack of an extra function call from a version that uses malloc().
Second, no, using A0 as a return value for pointers is not a bug in the compiler, and has not been since 1990, when this interesting book entitled "System V ABI Motorola 68000 Processor Family Supplement" was written. Allow me to quote a snippet from page 3-14 of that book:
%a0 Pointer return values appear in %a0. When calling a function that returns a structure or union, the caller allocates space for the return value and sets %a0 to its address. A function that returns a structure or union value places the same address in %a0 before it returns.
To this day, ELF-conforming implementations do it this way. Really. Go look it up, if you wish; the ISBN is 0-13-877663-6.
Eh, I guess I've lost you here.
What "mind-boggling tricks" are you talking about? There are no "tricks" here; the "static" keyword is pretty very clear.