1. The Joy of
Programming
Allocation of Local Variables in Stack
S.G. GANESH
It is always fun to understand the low-level details of a program and to explore
how compilers work. In this column, we’ll look at some details on how local
variables are allocated in stack and some interesting issues on how compilers
handle it.
very month, I get lots of mails and queries from example, an accumulator register in processors that are
E
LFY readers. This column seems to have accumulator based. So, it is likely that the same register that
become popular, particularly among students. is used for initialising the value of i is reused for reading the
This month, we’ll cover an interesting question argument passed to printf. So, 10 might get printed! Yes,
from Saravanan Swamy (GCT, Coimbatore). His compilers differ considerably in the ways in which they
question is: “Why does the following program print 10?” generate code, but they are also similar in many ways in
which they make use of the processor resources. So, it is not
int i = 10; pure coincidence if you get 10 printed even when you try
printf(“%d”); different compilers (even on different platforms).
If you are not convinced with my explanation, first try
Note that printf doesn’t obviously have i as the out this code in different platforms (by platform, I mean a
matching argument for the format string “%d”. So, the microprocessor, operating system and compiler
program is incorrect and you can reasonably expect the combination); second, take a look at the generated assembly
program to print some garbage value. But also note that it is code by different compilers for small pieces of code like this.
equally possible that you might get 10 as the output. Why? Even if this program doesn’t work and prints 10 in your
To understand this, let us see how the compiler might platform, there is much to learn from this exercise.
transform these statements to a low-level executable code. Now let us discuss one more aspect of local variables. If
Local variables are allocated in the stack frame of a you declare some local variables, they would typically be
function. When the main method is invoked, the storage allocated contiguously in the stack. Try this:
space for i is also allocated in the stack frame. A compiler
should generate code to initialise that value i with 10. The int i = 0, j = 10, k = 0;
machine code will have instructions to load the value 10 in a int *p = &j;
register and store it in the location for i in the stack frame. *(p - 1) = 10;
The printf statement is a function call. The printf *(p + 1) = 10;
function takes a variable length argument list. Based on the printf(“i = %d j = %d k = %d”, i, j, k);
first argument—the format string—the rest of the // most compilers will print
arguments are “interpreted”. Here the format string (“%d”) // i = 10 j = 10 k = 10
indicates that it should read the second argument and
interpret it as an integer. The printf takes the variable Here we attempt to check if the local variables i, j and k
length argument list as the argument and the compiler has are contiguously allocated by modifying local variables i and
no knowledge about the internal affairs of routines like k through a pointer p, which points to the address of j. It is
printf. So, it will compile the code without complaint very likely that you’ll get values 10 for i, j and k. But things
(though a tool like Lint will give a warning, but that’s a can go wrong also. For example, compilers can do
different story). optimisations and can decide that i and k are not modified
The compiler generates code for invoking printf. in the program and statically replace i and k in printf
Conventionally, a compiler would generate code to pass the with 0s!
arguments in the processor registers. For UNIX/Linux, the
code for printf will be in a shared library (typically named
libc). That printf code, with “%d” as an argument, expects By: S.G. Ganesh is a research engineer in Siemens
an integer to follow it. It has the code to read the argument (Corporate Technology), Bangalore. He has authored a
from a processor register. It so happens that most of the book, “Deep C” (ISBN 81-7656-501-6). You can reach him
at sgganesh@gmail.com
compilers generate code by reusing the same registers—for
124 NOVEMBER 2007 | LINUX FOR YOU | www.linuxforu.com
CMYK