Detect direction of stack growth

Discussion in 'C Programming' started by Adam Warner, Dec 27, 2004.

  1. Adam Warner

    Adam Warner Guest

    Hi all,

    Is this a (C99) portable way to detect whether the C stack grows upwards
    (1) or downwards (-1)?

    #include <stdio.h>

    int stack_direction=0;

    void detect_stack_direction(void * stack_start) {
    void * stack_current;
    stack_direction=-1;
    if (&stack_start<&stack_current) stack_direction=1;
    }

    int main() {
    void * stack_start;
    detect_stack_direction(stack_start);

    printf("Stack grows: %i\n", stack_direction);
    return 0;
    }

    Thanks,
    Adam
    Adam Warner, Dec 27, 2004
    #1
    1. Advertising

  2. Adam Warner <> writes:
    > Is this a (C99) portable way to detect whether the C stack grows upwards
    > (1) or downwards (-1)?


    No. There is no portable way to do this. Applying a relational
    operator to addresses of distinct objects (objects that are not
    contained in some larger composite object) invokes undefined behavior.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 27, 2004
    #2
    1. Advertising

  3. Adam Warner

    Adam Warner Guest

    Hi Keith Thompson,

    > Adam Warner <> writes:
    >> Is this a (C99) portable way to detect whether the C stack grows
    >> upwards (1) or downwards (-1)?

    >
    > No. There is no portable way to do this. Applying a relational
    > operator to addresses of distinct objects (objects that are not
    > contained in some larger composite object) invokes undefined behavior.


    Can I cast the addresses of the objects on the stack to uint64_t
    (7.18.1.1) and use a relational operator upon those values? This type
    is defined for all conforming implementations with 64 bit integers.

    What practically portable method exists to perform pointer arithmetic via
    integers? Does one first perform an implementation-specific check upon the
    size of the address space? Can I practically rely upon the address space
    never being larger than 64 bits?

    Thanks again,
    Adam
    Adam Warner, Dec 27, 2004
    #3
  4. Adam Warner

    xarax Guest

    "Adam Warner" <> wrote in message
    news:p...
    > Hi Keith Thompson,
    >
    > > Adam Warner <> writes:
    > >> Is this a (C99) portable way to detect whether the C stack grows
    > >> upwards (1) or downwards (-1)?

    > >
    > > No. There is no portable way to do this. Applying a relational
    > > operator to addresses of distinct objects (objects that are not
    > > contained in some larger composite object) invokes undefined behavior.

    >
    > Can I cast the addresses of the objects on the stack to uint64_t
    > (7.18.1.1) and use a relational operator upon those values? This type
    > is defined for all conforming implementations with 64 bit integers.


    You cannot get any meaningful information. Stack management
    is implementation dependent. Some implementations grow down,
    some grow up, some are segmented, some grow in either direction.

    Forget about it.

    > What practically portable method exists to perform pointer arithmetic via
    > integers?


    Pointer arithmetic is only meaningful for addresses within a single object.

    > Does one first perform an implementation-specific check upon the
    > size of the address space?


    A meaningless question.

    > Can I practically rely upon the address space
    > never being larger than 64 bits?


    No. That presumes a linear address space. An address space
    need not be linear. IBM mainframe architecture has non-linear
    virtual spaces with 64-bit "addresses" and 25-bit "space designation".
    Somewhat like trying to compare two complex numbers for greater-than
    or less-than; non-sensical. Only equals or unequals has meaning when
    comparing two objects that may not be the same object.
    xarax, Dec 27, 2004
    #4
  5. Adam Warner <> writes:
    > Hi Keith Thompson,
    >> Adam Warner <> writes:
    >>> Is this a (C99) portable way to detect whether the C stack grows
    >>> upwards (1) or downwards (-1)?

    >>
    >> No. There is no portable way to do this. Applying a relational
    >> operator to addresses of distinct objects (objects that are not
    >> contained in some larger composite object) invokes undefined behavior.

    >
    > Can I cast the addresses of the objects on the stack to uint64_t
    > (7.18.1.1) and use a relational operator upon those values? This type
    > is defined for all conforming implementations with 64 bit integers.


    It would make more sense to cast to intptr_t or uintptr_t (assuming a
    C99 implementation), but these types aren't guaranteed to exist, and
    even if they do they aren't guaranteed to behave the way you want them
    to.

    > What practically portable method exists to perform pointer arithmetic via
    > integers?


    None.

    > Does one first perform an implementation-specific check upon the
    > size of the address space? Can I practically rely upon the address space
    > never being larger than 64 bits?


    Addresses can't necessarily be interpreted as integers. There has to
    be some stack-like first-in last-out data structure to support nested
    function calls, including recursion, but there's not necessarily any
    particular ordering between objects corresponding to deeper and
    shallower calls.

    Relational operators ("<", "<=", ">", ">=") on pointers apply only
    within an object. Otherwise, as far as the C standard is concerned,
    there is no ordering relationship.

    Of course there can be meaningful ordering of pointer values on many
    implementations, but not all. I think IBM's AS/400 is an example of a
    system that can support a conforming C implementation, but on which
    pointers don't behave anything like what you might expect.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 27, 2004
    #5
  6. Adam Warner

    Adam Warner Guest

    In <> on Mon, 27 Dec 2004 09:39:06 +0000, Keith Thompson wrote:
    X-Pan-Internal-Sendlater-Newsgroups: comp.lang.c
    X-Pan-Internal-Post-Server: news.individual.net
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit

    Hi Keith Thompson,

    In <> on Mon, 27 Dec 2004 09:39:06 +0000,
    Keith Thompson wrote:
    > Addresses can't necessarily be interpreted as integers. There has to
    > be some stack-like first-in last-out data structure to support nested
    > function calls, including recursion, but there's not necessarily any
    > particular ordering between objects corresponding to deeper and
    > shallower calls.
    >
    > Relational operators ("<", "<=", ">", ">=") on pointers apply only
    > within an object. Otherwise, as far as the C standard is concerned,
    > there is no ordering relationship.
    >
    > Of course there can be meaningful ordering of pointer values on many
    > implementations, but not all. I think IBM's AS/400 is an example of a
    > system that can support a conforming C implementation, but on which
    > pointers don't behave anything like what you might expect.


    Thanks Keith! I was attempting to ascertain the extent of the stack so I
    could check it for potential pointers to heap allocated objects in order
    to implement a simple garbage collector. I still have one outstanding
    concern that a live pointer to the heap might exist solely within a
    CPU register.

    But at this stage I'm far better off dropping in the Boehm-Demers-Weiser
    garbage collector and tacking easier issues.

    I'm really enjoying learning C. Thanks for your responses.

    Regards,
    Adam
    Adam Warner, Dec 27, 2004
    #6
  7. Adam Warner

    Malcolm Guest

    "Adam Warner" <> wrote
    >
    > Thanks Keith! I was attempting to ascertain the extent of the stack so I
    > could check it for potential pointers to heap allocated objects in order
    > to implement a simple garbage collector. I still have one outstanding
    > concern that a live pointer to the heap might exist solely within a
    > CPU register.
    >
    > But at this stage I'm far better off dropping in the Boehm-Demers-Weiser
    > garbage collector and tacking easier issues.
    >

    Garbage collection is inherently compiler-dependent.

    If you want to investigate pointers, the portable way to do it is to print
    out the value of the pointer usings the %p specifier. For most practical
    purposes, this will tell you what stack management technique your compiler
    uses. However be aware that a conforming compiler might do something really
    unusual, such as splitting the stack into 16K segments and growing one
    upwards and one downwards. Really you need to get the compiler documentation
    to be sure you ar enot caught out.
    Malcolm, Dec 27, 2004
    #7
    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. Generic Usenet Account

    Tracking the "memory growth" of a process

    Generic Usenet Account, Apr 5, 2004, in forum: C++
    Replies:
    5
    Views:
    464
    Kevin Goodsell
    Apr 6, 2004
  2. Generic Usenet Account

    Tracking the "memory growth" of a process

    Generic Usenet Account, Apr 5, 2004, in forum: C Programming
    Replies:
    4
    Views:
    333
    Kevin Goodsell
    Apr 6, 2004
  3. sam
    Replies:
    3
    Views:
    369
    Kent Johnson
    Mar 19, 2005
  4. direction of stack growth

    , Apr 19, 2006, in forum: C Programming
    Replies:
    18
    Views:
    630
    Jack Klein
    Apr 20, 2006
  5. gary
    Replies:
    3
    Views:
    1,459
    EventHelix.com
    Oct 23, 2005
Loading...

Share This Page