t1.c:
#include <stdio.h>
int main()
{
int i = 0;
printf("%d\n", &i);
return 0;
}
t2.c:
#include <stdio.h> int main() { int i=0; int *p; scanf("%d", &i); p = (int *)(i-8); *p = 45; int j; printf("%d\n", j); p += 2; *p = 3; printf("%d\n", i); return 0; }
Following which:
[coelacanth ~ 05:42:15]$ ./t1 | ./t2
45
3
What's cute about this otherwise unremarkable bit of pointer mayhem: the thoughts that eventually culminated in its existence were given their start by The Intentionality of Human Action.
The things that people do to their stacks...
But I don't understand -- is the piped input from t1 really necessary? Or, is that the point?
Posted by: arthegall | January 19, 2009 at 04:56 AM
It's part of the point—while the input from t1 in this case is obviously tendentious given how it was generated, that same input could come from anything and be, fortuitously, the address of something t2 can manipulate without segfaulting.
Posted by: Ben Wolfson | January 19, 2009 at 09:18 AM
That is not cute. Kitties are cute.
Posted by: bitchphd | January 20, 2009 at 03:41 PM
Is stack organization part of the C/C++ language definition, or is this program's output dependent on the compiler you use?
Posted by: The Modesto Kid | January 22, 2009 at 11:13 AM
I think it's architecture-dependent but I'm not certain of that.
Posted by: Ben Wolfson | January 22, 2009 at 11:14 AM
So you're saying, it's like one of them thar trolley problems that you philosophers seem so fond of, but with pointers to the stack instead of people tied to the rails.
I agree with TMK, that the particular behavior may be entirely architecture dependent...
Posted by: arthegall | January 27, 2009 at 03:09 AM