[comp.lang.c] _stklen in Turbo C

boogaard@ruunsa.fys.ruu.nl (Martin vdBoogaard) (02/06/91)

For a variety of reasons I'd like to be able to compile (on a DOS machine
with Turbo C) with a stack that is larger than the usual 4kB. The manual
(yes, I *have* read the FM) says I should simply set _stklen (defined in
dos.h) to the desired value. I just can't find out where. If I put e.g.

  _stklen = 10000;

at the start of main (), nothing happens, i.e. when I deliberately cause
a stack overflow by some silly recursion, the number of times my
stack-consuming function can call itself before triggering the `Stack
overflow!' run-time error is always the same. (I can even make _stklen 0
if I like.) Actually, I don't understand how a program would be able to
change its own stack size at run time. Is this really what happens (or,
in my case, doesn't happen)? Who has a working example of how to do this?


Thanks,

Martin J. van den Boogaard         | Dept. of Atomic & Interface Physics
                                   | Debye Institute--Utrecht University
boogaard@fys.ruu.nl                | P.O. Box 80.000, NL-3508 TA Utrecht
boogaard@hutruu51.bitnet           | the Netherlands, +31 30 532904
------------------------------------------------------------------------

jdb@palmetto.cis.ufl.edu (Brian K. W. Hook) (02/06/91)

In article <1921@ruunsa.fys.ruu.nl> boogaard@ruunsa.fys.ruu.nl (Martin vdBoogaard) writes:
>For a variety of reasons I'd like to be able to compile (on a DOS machine
>with Turbo C) with a stack that is larger than the usual 4kB. The manual
>(yes, I *have* read the FM) says I should simply set _stklen (defined in
>dos.h) to the desired value. I just can't find out where. If I put e.g.
>
>  _stklen = 10000;
>
>at the start of main (), nothing happens, i.e. when I deliberately cause
>a stack overflow by some silly recursion, the number of times my
>stack-consuming function can call itself before triggering the `Stack
>overflow!' run-time error is always the same. (I can even make _stklen 0
>if I like.) Actually, I don't understand how a program would be able to
>change its own stack size at run time. Is this really what happens (or,
>in my case, doesn't happen)? Who has a working example of how to do this?

Well, if you look at the code in the Turbo C++ Docs (which is all I have)
then you will notice that it states that you should define _stklen
as an extern.  _stklen is an internal variable that I BELIEVE is used
as part of the start-up C module....?

Anyway, here is how I do it (and it does work!)

#include /* Whatever needs to be include */

extern unsigned _stklen=8192;  /* This is off the top of my head, but I    */
                               /* believe _stklen is an unsigned int, but  */
                               /* it could be signed...                    */
void main ( void )   /* Of course you could change the args and returns */
{

/*
** Put your code here
*/

}

The key here is the extern declaration, that lets the compiler know that you
are referring to a variable that is in another module (the startup module
I believe)....If you put the declaration inside main() it wouldn't work,
especially if you didn't declare it an extern (if you didn't, TC would just
believe that you are declaring a new local variable).

Hope this helps,

Brian

dubner@hpspkla.spk.hp.com (Joe Dubner) (02/06/91)

> For a variety of reasons I'd like to be able to compile (on a DOS machine
> with Turbo C) with a stack that is larger than the usual 4kB. The manual
> (yes, I *have* read the FM) says I should simply set _stklen (defined in
> dos.h) to the desired value. I just can't find out where. If I put e.g.
> 
>   _stklen = 10000;
> 
> at the start of main (), nothing happens, i.e. when I deliberately cause
> a stack overflow by some silly recursion, the number of times my
> stack-consuming function can call itself before triggering the `Stack
> overflow!' run-time error is always the same. (I can even make _stklen 0
> if I like.) Actually, I don't understand how a program would be able to
> change its own stack size at run time. Is this really what happens (or,
> in my case, doesn't happen)? Who has a working example of how to do this?


Chalk this up to a quirk (bug? Or design decision?) in TC++.  (I assume
you're using it -- I don't know about TC 2.0).  _stklen needs to be set
_outside_ of any function and _before_ any code is generated (before
your first linked function) if stack overflow checking is enabled (and I
assume it is in your case, judging by the 'Stack Overflow!' message).

For example:

extern unsigned _stklen = 16 * 1024;

main()
{}

other_functions()
{}

I'll bet this fixes it for you!

Joe

--------------------------------------------------------------------------
Joe Dubner     K7JD  |  Hewlett Packard Company  |  dubner@hpspkla.HP.COM
                     |  TAFC-34         M.S. 2I  |   (509) 921-3514 
                     |  Spokane, WA  99220  USA  | 
--------------------------------------------------------------------------

kooijman@duteca (Richard Kooijman) (02/07/91)

boogaard@ruunsa.fys.ruu.nl (Martin vdBoogaard) writes:

>For a variety of reasons I'd like to be able to compile (on a DOS machine
>with Turbo C) with a stack that is larger than the usual 4kB. The manual
>(yes, I *have* read the FM) says I should simply set _stklen (defined in
>dos.h) to the desired value. I just can't find out where. If I put e.g.

>  _stklen = 10000;

>at the start of main (), nothing happens, i.e. when I deliberately cause
>a stack overflow by some silly recursion, the number of times my
>stack-consuming function can call itself before triggering the `Stack
>overflow!' run-time error is always the same. (I can even make _stklen 0
>if I like.) Actually, I don't understand how a program would be able to

Turbo C doesn't do this at run-time, maybe sort of at run-time, but it
uses the value of _stklen to reserve space, which can be done at compile-time
or run-time. Maybe the start-up code reserves the space, so then it may be
called a run-time space allocation, but you cannot change _stklen anyfurther
in your program, so then it maybe called compile-time allocation.

You must declare _stklen as follows as a global (!) definition:

extern unsigned _stklen = 10000;

So this must go outside of main().



Richard.

boogaard@ruunsa.fys.ruu.nl (Martin vdBoogaard) (02/08/91)

Thanks to all the people who responded to my question about the use of
_stklen in Turbo C. As was pointed out, statements like

  extern unsigned _stklen = 10000;

have to be made outside any function. And indeed, all this could have
been found in the HELPME!.DOC file. Having been told how to do the
trick, I have tried to detect the influence of assignements like this.
However, nothing happened, because I was using the medium memory model.
This brings up a second question, i.e. when does Turbo C (with the -N
compiler option) signal a stack overflow?

Let's call the current size of the heap H and the size of the static
data D. Stack overflow is signaled by your program when the current stack
size exceeds S_max. It seems to me that in Turbo C's small-data memory
models (tiny, small, medium) at any time we simply have S_max = 64kB - H
- D, in other words: the value of _stklen is in this case completely
irrelevant. In the large-data memory models (compact, large, huge) the
role of _stklen is what you expect it to be: S_max = _stklen.

All this is, as far as I know, not in Borland's manuals. The section on
the -N compiler option hails the stack overflow detection as `a real
lifesaver', but there is no adequate info on what to do about stack
overflow (except simplifying your code and minimizing the use of local
variables) and what the choice of the memory model has got to do with
this. Is there any reason why we're not able to simply tell TLINK how
large we want the stack to be?


Martin J. van den Boogaard         | Dept. of Atomic & Interface Physics
                                   | Debye Institute--Utrecht University
boogaard@fys.ruu.nl                | P.O. Box 80.000, NL-3508 TA Utrecht
boogaard@hutruu51.bitnet           | the Netherlands, +31 30 532904
------------------------------------------------------------------------