Re: Direction in which the process stack grows

From: Måns Rullgård (mru_at_inprovide.com)
Date: 03/05/05


Date: Sat, 05 Mar 2005 21:15:35 +0100

Jens.Toerring@physik.fu-berlin.de writes:

> candy_init@yahoo.com wrote:
>> Can anybody tell me that whether the following code is a reliable
>> method to check the direction in which the process stack grows on the
>> given platform:
>
>> #include <stdio.h>
>
>> int main(void)
>> {
>> int c1;
>> int c2;
>> int *ptr=&c1;
>> int *ptr1=&c2;
>> if((ptr1-ptr)>0)
>> printf("stack grows upwards\n");
>> else
>> printf("stack grows downwards\n");
>> return 0;
>> }
>
> No, it isn't. First the pedantic point of view: comparing pointers
> to different objects in C results in undefined behaviour, meaning
> that there is no way you ever can be sure that the result has any
> resonable meaning (but then the C standard doesn't even require
> that there's a stack at all;-)
>
> But, from a more practical point of view, there is nothing that
> would force the compiler to create local variables in the same
> sequence on the stack as you define them in the source code. For
> that reason I would guess that the following is a somewhat more
> robust approach:
>
> include <stdio.h>
>
> void f1( char *a ) {
> char b = '*';
> printf( "Stack grows %s\n", &b > a ? "downwards" : "upwards" );
> }
>
> int main( void )
> {
> char a = 42;
> f1( &a );
> return 0;
> }
>
> But you must make sure that the compiler gets invoked in a way
> that it won't inline functions. When I compile the above program
> with gcc and either without optimization or inlining explicitely
> switched off, i.e. with one of
>
> gcc -O0 -W -Wall -ansi -pedantic -o stack_dir stack_dir.c
> gcc -O3 -fno-inline -W -Wall -ansi -pedantic -o stack_dir stack_dir.c
>
> the output is "Stack grows upwards". By the way, your program gave
> me the opposite answer...
>
> Another observation: when I declare the variable 'b' as volatile
> and compile with '-O3' and without disabling function inlining
> then the output is "Stack grows downwards" - just shows how easy
> it is to get this wrong;-)

Autoconf uses this method:

int
find_stack_direction()
{
    static char *addr = 0;
    auto char dummy;

    if(addr == 0) {
        addr = &dummy;
        return find_stack_direction();
    } else
        return (&dummy > addr) ? 1 : -1;
}

int
main()
{
    printf("Stack grows %s\n", find_stack_direction() < 0? "down": "up");
}

Notice how the use of recursion stops the compiler from inlining.
Incidentally, this reports the stack growing downwards, which is also
correct on all my machines (x86 and Alpha).

-- 
Måns Rullgård
mru@inprovide.com


Relevant Pages

  • Re: calling convention stdcalll and cdecl call
    ... the compiler can somehow figure out how the function accesses its parameters, it can figure out how many there are, and pop the stack correctly without any additional information from the caller. ... int find{ ... This is similar to how it must take some action for a __stdcall member function, ...
    (microsoft.public.vc.language)
  • Re: where do the automatic variables go ?
    ... and bss segments etc...but there is notthing like stack and heap ... Stack variables are implied by the compiler (the compiler generates code ... int foo ...
    (comp.os.linux.misc)
  • Re: Value Types and Reference Types
    ... the compiler doesn't have a list of them. ... So your saying that an int is not special? ... put it on the stack". ... Int32 x; are pretty much identical except for speed/memory issues. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Sweeney presentation "The Next Mainstream Language"
    ... Specify int to be more specific than real. ... Reals with sufficient precision can work as bounded integers with no ... Annotations need to be verified by the compiler, ... and/or compiler-checked stack allocation. ...
    (comp.lang.functional)
  • arguments of inline functions
    ... Experience tells me that if I change an argument inside an inline function, ... void __forceline F(int i, int j) ... So I guess the compiler creates new integers when it does the inlining, ...
    (microsoft.public.vc.language)

Loading