Memory location for local C variables

Discussion in 'C Programming' started by Pete, May 11, 2008.

  1. Pete

    Pete Guest

    Is there a way to cause gcc to place local C variables onto the stack
    in the order they are defined in the source code? I have been
    experimenting with how gcc converts C code to machine code and have
    found that no matter how I define a function's local variables, they
    are always stored in the same order on the stack.

    For example, whether I define a the function like this:

    int test_function() {
    int flag = 0;
    char buffer[20];
    ...
    }

    or like this:

    int test_function() {
    char buffer[20];
    int flag = 0;
    ...
    }

    I have found that buffer will always be placed on the stack after the
    flag (that is buffer's memory address will be lower than flag's)... at
    least on a machine running FreeBSD 7.

    Any advise would be greatly appreciated since I have been unable to
    find any answers by reading the manpages and various articles on
    google.
     
    Pete, May 11, 2008
    #1
    1. Advertising

  2. Pete

    Ian Collins Guest

    Pete wrote:
    > Is there a way to cause gcc to place local C variables onto the stack
    > in the order they are defined in the source code? I have been
    > experimenting with how gcc converts C code to machine code and have
    > found that no matter how I define a function's local variables, they
    > are always stored in the same order on the stack.
    >

    Well a gcc group would be the place to ask.

    > For example, whether I define a the function like this:
    >
    > int test_function() {
    > int flag = 0;
    > char buffer[20];
    > ...
    > }
    >
    > or like this:
    >
    > int test_function() {
    > char buffer[20];
    > int flag = 0;
    > ...
    > }
    >
    > I have found that buffer will always be placed on the stack after the
    > flag (that is buffer's memory address will be lower than flag's)... at
    > least on a machine running FreeBSD 7.
    >

    Why do you care?

    --
    Ian Collins.
     
    Ian Collins, May 11, 2008
    #2
    1. Advertising

  3. Pete

    Bart Guest

    On May 11, 1:39 am, Pete <> wrote:
    > Is there a way to cause gcc to place local C variables onto the stack
    > in the order they are defined in the source code? I have been
    > experimenting with how gcc converts C code to machine code and have
    > found that no matter how I define a function's local variables, they
    > are always stored in the same order on the stack.


    It sounds a bit dangerous relying on variables being in a particular
    order.

    There could be any number of reasons for the choice of the compiler,
    for example they might simply be in alphabetical order.

    For more control you can try enclosing the variables in a struct.

    --
    Bartc
     
    Bart, May 11, 2008
    #3
  4. Pete

    Pete Guest

    On May 10, 9:00 pm, Ian Collins <> wrote:
    > Pete wrote:
    > > Is there a way to cause gcc to place local C variables onto the stack
    > > in the order they are defined in the source code? I have been
    > > experimenting with how gcc converts C code to machine code and have
    > > found that no matter how I define a function's local variables, they
    > > are always stored in the same order on the stack.

    >
    > Well a gcc group would be the place to ask.
    >
    >
    >
    > > For example, whether I define a the function like this:

    >
    > > int test_function() {
    > > int flag = 0;
    > > char buffer[20];
    > > ...
    > > }

    >
    > > or like this:

    >
    > > int test_function() {
    > > char buffer[20];
    > > int flag = 0;
    > > ...
    > > }

    >
    > > I have found that buffer will always be placed on the stack after the
    > > flag (that is buffer's memory address will be lower than flag's)... at
    > > least on a machine running FreeBSD 7.

    >
    > Why do you care?
    >
    > --
    > Ian Collins.


    Asking a gcc group was my second choice... and I dont REALLY care that
    much. I was "working through" some examples in a C/assembly tutorial I
    found online and it mentioned that by changing the order they were
    defined in the source, you can change the order on the stack. It
    wasn't really important, but since it didn't work it "perked" my
    curiosity.

    Thanks for the response.
     
    Pete, May 11, 2008
    #4
  5. Pete <> writes:
    > On May 10, 9:00 pm, Ian Collins <> wrote:
    >> Pete wrote:
    >> > Is there a way to cause gcc to place local C variables onto the stack
    >> > in the order they are defined in the source code? I have been
    >> > experimenting with how gcc converts C code to machine code and have
    >> > found that no matter how I define a function's local variables, they
    >> > are always stored in the same order on the stack.

    >>
    >> Well a gcc group would be the place to ask.
    >>
    >> > For example, whether I define a the function like this:

    >>
    >> > int test_function() {
    >> > int flag = 0;
    >> > char buffer[20];
    >> > ...
    >> > }

    >>
    >> > or like this:

    >>
    >> > int test_function() {
    >> > char buffer[20];
    >> > int flag = 0;
    >> > ...
    >> > }

    >>
    >> > I have found that buffer will always be placed on the stack after the
    >> > flag (that is buffer's memory address will be lower than flag's)... at
    >> > least on a machine running FreeBSD 7.

    >>
    >> Why do you care?

    >
    > Asking a gcc group was my second choice... and I dont REALLY care that
    > much. I was "working through" some examples in a C/assembly tutorial I
    > found online and it mentioned that by changing the order they were
    > defined in the source, you can change the order on the stack. It
    > wasn't really important, but since it didn't work it "perked" my
    > curiosity.


    Curiosity is good, but you need to find a better tutorial (unless it's
    intended to describe one particular implementation. The C language
    doesn't even guarantee the existence of a "stack" in the sense you're
    probably thinking of, and says nothing about the order in which local
    variables are allocated. Changing the order of declaration *might*
    change the allocation order for some implementation; apparently it
    doesn't for gcc.

    If the behavior of your program depended on the order, then your
    program would need to be corrected.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 11, 2008
    #5
  6. Pete

    Ian Collins Guest

    Pete wrote:
    > On May 10, 9:00 pm, Ian Collins <> wrote:
    >> Why do you care?

    >
    > Asking a gcc group was my second choice... and I dont REALLY care that
    > much. I was "working through" some examples in a C/assembly tutorial I
    > found online and it mentioned that by changing the order they were
    > defined in the source, you can change the order on the stack. It
    > wasn't really important, but since it didn't work it "perked" my
    > curiosity.
    >

    Such details are best left to the implementation.

    The order is undefined by the standard and may change with different
    options and optimisations with the same compiler. Local variables my be
    optimised to registers and not appear on "the stack", assuming there is
    one...

    If you want a fixed order, use a struct.

    --
    Ian Collins.
     
    Ian Collins, May 11, 2008
    #6
  7. Pete

    Chris Torek Guest

    In article <>
    Pete <> wrote:
    >Is there a way to cause gcc to place local C variables onto the stack
    >in the order they are defined in the source code?


    Yes: modify the compiler source. :)

    (Seriously, gnu.gcc.help, or one of the mailing lists, is a better
    place for gcc-specific questions. I do not know everything about
    enough versions of gcc to say *for certain* that the answer to the
    question I think you intended to ask -- ie, whether there are
    compile-time flags and/or pragmas / and/or other existing mechanisms
    to control this sort of thing, without modifying gcc itself -- is
    "no", but I think that is the answer.)

    >I have been experimenting with how gcc converts C code to machine
    >code and have found that no matter how I define a function's local
    >variables, they are always stored in the same order on the stack.

    [which you later note conflicts with a statement in a C tutorial]

    The problem here is that the C tutorial you have been using is
    wrong.

    There is a general rule that applies here though, to all compilers
    (not just gcc, and not just C compilers). *In general* (and there
    will be exceptions), the "smarter" a compiler is, the less resemblance
    you will find between "original source code" and "final machine-level
    code". A compiler is simply a tool for taking a sort of "statement
    of intent", represented in some source-code language, and turning
    it into another, different, "statement of intent" -- normally in
    some other, "lower level" language, such as assembler or machine
    language -- that has the "same meaning" but is somehow "better"
    for some particular purpose(s) (typically "execution speed", and
    sometimes code size comes into play as well).

    When the source language is "imperative" (statement or "command
    sequence" oriented languages like C, Pascal, Fortran, Ada, etc.,
    fall into this family) and "sequential" (most imperative languages
    view execution as a "sequence of events", rather than some sort of
    nondeterministic or parallel/simultaneous evaluation, although
    there are some exceptions), the compilation process involves
    analyzing the semantics of the sequence of "do this, then do that;
    then, while condition X holds, do some other things" commands, and
    finding an equivalent -- but preferably simpler, faster, etc --
    sequence that achieves the same results. If the target language
    is machine language, the final sequence is "machine instructions",
    but one can (e.g.) compile things like C++ to C, as early C++
    compilers did (though today, few use this path, for various reasons).

    A "dumb" compiler will take your original source code constructs
    and apply whatever small, simple, and obvious mappings are needed
    to make the target language achieve the required results. So "do
    step 1, then do step 2; then, while X holds, do steps 3 and 4"
    generally becomes:

    do step 1
    do step 2
    loop:
    test X
    if test fails, goto end_loop
    do step 3
    do step 4
    goto loop
    end_loop:

    (since most target languages have this sort of label/goto ability).
    A "smarter" compiler, however, may realize that "step 2" is mostly
    redundant, and that step 3 never changes and it is OK to compute
    it once, and produce:

    do step 1
    do a little bit of step 2
    test X
    if test fails, goto end_loop
    temp = do step 3
    loop:
    use temp to pretend to do step 3
    do step 4
    test X
    if test succeeds, goto loop
    end_loop:

    The more "smarts" the compiler can apply, the more of the original
    code it can move, alter, remove, replace, or refine. The more this
    sort of work is pushed towards the latest stages of "compiling"
    (e.g., by doing code-generation at link time, when you do "xlink
    foo.o bar.o baz.o" instead of when you do "xcompile foo.c"), the
    more likely one is to find that entire functions have been moved
    around, formal parameters replaced with their actual arguments,
    constants propagated, swathes of unreachable code removed, and so
    on. (The compilation will take much longer but the code may run
    significantly faster. Of course, one tiny source-level change, to
    replace a constant argument with a runtime input value, may require
    putting all the removed code back again.)

    All of the above may seem sort of abstract and theoretical, perhaps
    because it *is*, but there is a key point here, and that is: the
    most important part of your source code is not its *syntax* (the
    spelling, word-order, and so on) but rather its *semantics* (the
    things that every compiler is obliged to *do*, or at least "appear
    to have done", when the code is run). The semantics are the
    *meaning* of the code, and a compiler's job is to preserve this
    meaning, not mere spelling. The syntax is not *irrelevant* -- it
    matters a lot to human readers, who tend to use it as a shortcut
    to understanding the language-provided semantics, and moreover, to
    glean some additional "deeper meaning" that is not contained in
    the source-code language[%] -- but it is not crucial to the
    compilation, at least. (There are some languages, like Python, in
    which syntax *is* semantically meaningful, though.)

    (If anyone ever says something like "bah, mere semantics", you know
    they have lost the argument. :) It seems a bit peculiar to me that
    the word "semantics" is used in ordinary conversation to "refer to
    a trivial point ... that revolves around mere words" [see
    <http://dictionary.reference.com/browse/semantics>, when words are
    often the only tool we have to communicate. If the words are all
    we have, how can they be "mere"?)

    [% This "deeper meaning" is the programmer's *intent*. Humans can
    look at the names of variables and functions, and attempt to figure
    out *why* you are looping six times here, or computing square roots
    there. Of course, as a programmer, you should also consider writing
    comments that explicate your intent. The source code will, via
    the language's semantics, already say "what to do"; you should
    endeavor to add "why I do it this way here". That is, you should
    add even more semantic information, above and beyond that required
    by the source-code language. You should aim this information at
    whoever will work on your code in the future. Even if that person
    is "yourself a year later", you may find it very useful.]
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
     
    Chris Torek, May 11, 2008
    #7
  8. On 11 May 2008 at 3:29, Keith Thompson wrote:
    > Changing the order of declaration *might* change the allocation order
    > for some implementation; apparently it doesn't for gcc.


    The most obvious reason for the compiler to rearrange the order of local
    variables on the stack is to avoid wasting space unnecessarily if the
    variables need different alignments. Of course, as someone else pointed
    out the compiler can also sometimes eliminate local variables
    completely, or store them in a register.
     
    Antoninus Twink, May 15, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sandy

    memory allocation of local variables

    sandy, Dec 13, 2006, in forum: C Programming
    Replies:
    2
    Views:
    398
    Stephen Sprunk
    Dec 13, 2006
  2. Sullivan WxPyQtKinter
    Replies:
    10
    Views:
    706
    Antoon Pardon
    Nov 8, 2007
  3. Rahul
    Replies:
    22
    Views:
    835
    Richard Herring
    Feb 13, 2008
  4. Tammo Tjarks
    Replies:
    2
    Views:
    303
    Tammo Tjarks
    Sep 13, 2007
  5. king
    Replies:
    2
    Views:
    185
    Tad McClellan
    Jun 27, 2006
Loading...

Share This Page