10 jo p oct 07

1

Click here to load reader

Upload: ganesh-sg

Post on 05-Dec-2014

440 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: 10 Jo P Oct 07

124 NOVEMBER 2007 | L INUX FOR YOU | www.linuxforu.com

C M Y K

very month, I get lots of mails and queries fromLFY readers. This column seems to havebecome popular, particularly among students.This month, we’ll cover an interesting questionfrom Saravanan Swamy (GCT, Coimbatore). His

question is: “Why does the following program print 10?”

int i = 10;

printf(“%d”);

Note that printf doesn’t obviously have i as thematching argument for the format string “%d”. So, theprogram is incorrect and you can reasonably expect theprogram to print some garbage value. But also note that it isequally possible that you might get 10 as the output. Why?To understand this, let us see how the compiler mighttransform these statements to a low-level executable code.

Local variables are allocated in the stack frame of afunction. When the main method is invoked, the storagespace for i is also allocated in the stack frame. A compilershould generate code to initialise that value i with 10. Themachine code will have instructions to load the value 10 in aregister and store it in the location for i in the stack frame.

The printf statement is a function call. The printf

function takes a variable length argument list. Based on thefirst argument—the format string—the rest of thearguments are “interpreted”. Here the format string (“%d”)indicates that it should read the second argument andinterpret it as an integer. The printf takes the variablelength argument list as the argument and the compiler hasno knowledge about the internal affairs of routines likeprintf. So, it will compile the code without complaint(though a tool like Lint will give a warning, but that’s adifferent story).

The compiler generates code for invoking printf.Conventionally, a compiler would generate code to pass thearguments in the processor registers. For UNIX/Linux, thecode for printf will be in a shared library (typically namedlibc). That printf code, with “%d” as an argument, expectsan integer to follow it. It has the code to read the argumentfrom a processor register. It so happens that most of thecompilers generate code by reusing the same registers—for

example, an accumulator register in processors that areaccumulator based. So, it is likely that the same register thatis used for initialising the value of i is reused for reading theargument passed to printf. So, 10 might get printed! Yes,compilers differ considerably in the ways in which theygenerate code, but they are also similar in many ways inwhich they make use of the processor resources. So, it is notpure coincidence if you get 10 printed even when you trydifferent compilers (even on different platforms).

If you are not convinced with my explanation, first tryout this code in different platforms (by platform, I mean amicroprocessor, operating system and compilercombination); second, take a look at the generated assemblycode by different compilers for small pieces of code like this.Even if this program doesn’t work and prints 10 in yourplatform, there is much to learn from this exercise.

Now let us discuss one more aspect of local variables. Ifyou declare some local variables, they would typically beallocated contiguously in the stack. Try this:

int i = 0, j = 10, k = 0;

int *p = &j;

*(p - 1) = 10;

*(p + 1) = 10;

printf(“i = %d j = %d k = %d”, i, j, k);

// most compilers will print

// i = 10 j = 10 k = 10

Here we attempt to check if the local variables i, j and kare contiguously allocated by modifying local variables i andk through a pointer p, which points to the address of j. It isvery likely that you’ll get values 10 for i, j and k. But thingscan go wrong also. For example, compilers can dooptimisations and can decide that i and k are not modifiedin the program and statically replace i and k in printf

with 0s!

S.G. GANESHIt is always fun to understand the low-level details of a program and to explorehow compilers work. In this column, we’ll look at some details on how localvariables are allocated in stack and some interesting issues on how compilershandle it.

The Joy ofProgrammingAllocation of Local Variables in Stack

By: S.G. Ganesh By: S.G. Ganesh By: S.G. Ganesh By: S.G. Ganesh By: S.G. Ganesh is a research engineer in Siemens

(Corporate Technology), Bangalore. He has authored a

book, “Deep C” (ISBN 81-7656-501-6). You can reach him

at [email protected]

E