Re: why does this work ?

From: Barry Schwarz (schwarzb_at_deloz.net)
Date: 10/11/03


Date: 11 Oct 2003 17:17:28 GMT

On Sat, 11 Oct 2003 12:53:07 +0200, Sidney Cadot <sidney@jigsaw.nl>
wrote:

>Joona I Palaste wrote:
>
>> <snip>
>> There is no requirement for implementations to *have* a stack in the first place.
>
>This is the second time I see this posted over the last couple of days,
>and you're surely right. But it does beg the following question:
>
>----
>
>#include <stdio.h>
>
>/* returns n! modulo 2^(number of bits in an unsigned long) */
>unsigned long f(unsigned long n)
>{
> return (n==0) ? 1 : f(n-1)*n;
>}
>
>int main(void)
>{
> unsigned long z;
> for(z=1;z!=0;z*=2)
> {
> printf("%lu %lu\n", z, f(z));
> fflush(stdout);
> }
> return 0;
>}
>
>----
>
>As far as I can see, this is a perfectly valid C program that should
>reach the 'return 0' statement always, were it not for the fact that in

It is valid in the theoretical sense but it executes in the real
world.

>all compilers I tried (one, actually) it terminates with a segmentation
>fault of some sort, due to limited stack size.
>
>Is this 'incorrect behavior' of all these compilers, or is there some
>wording in the Standard that covers for machines with a finite stack
>(much to my dismay, this covers all machines I have access to)?
>
>If so, is there a minimum depth of function calls that I can rely on to
>be executed properly? I would hate to rewrite all my programs to do
>everything within main() without function calls, for the ultimate
>portability :-)

All systems have limited resources. Even virtual memory is backed up
in some kind of file. I could not find in the standard a minimum for
the number of recursive function calls an implementation was required
to support. It does state that a function can be recursively called
at least once.

Do you know how much data your system must save when a function is
re-called? Usually, this includes information about the state of your
task (such as the address to return to) and all automatic variables
(those defined in your code and any generated by the compiler to hold
intermediate results). There is probably more that I cannot think of
at the moment. What would you accept as a reasonable estimate? 100
bytes just to make the arithmetic easier?

ULONG_MAX is required to be greater than 4,000,000,000 (that's billion
on my side of the pond but perhaps milliard on yours, 4*10^9 in any
case). What will happen when z is 10,000,000 (a mere 10 million)? f
will be recursively called 10 million times, requiring 1 gigabyte of
storage. Is your task authorized to consume that much of your system
resources? Does your system even have that much available? Even if
you can support this, can you support z at 100 million requiring 10
gigabtyes? At 4 billion (milliard) requiring 400 gigabytes? What
happens if long is 64 bits on your system?

Would you be asking your question if your program simply issued malloc
requests until no more memory was available? The only difference is
that malloc fails "politely" by returning NULL. There doesn't seem to
be any way for a recursion failure to be "polite." Both fail for
exactly the same reason. Only the symptoms of that failure are
different.

Welcome to the limitations of practicality.

<<Remove the del for email>>



Relevant Pages

  • Re: Industry Standard Security and guest wifi access best practice
    ... what is specifically unacceptable is requiring technician ... Could you elaborate on the "scale" that you're looking for? ... Availability of offsite support and admin? ... latest FON firmware has this feature. ...
    (alt.internet.wireless)
  • Re: RfD - Escaped Strings (long)
    ... This proposal selects the hexadecimal representation, requiring ... it avoids the endian problems involved ... for UTF16 and UTF32 support. ... Stephen Pelc, stephenXXX@xxxxxxxxxxxx ...
    (comp.lang.forth)
  • Re: RfD - Escaped Strings (long)
    ... This proposal selects the hexadecimal representation, requiring ... it avoids the endian problems involved ... for UTF16 and UTF32 support. ... The use of hex characters is not just to provide wide ...
    (comp.lang.forth)
  • remote access during runaway process
    ... On a remotely hosted Linux server, a developer's code went in to deep ... recursion, and all of the services on the system became unavailable, ... requiring a call to the hosting provider. ...
    (comp.os.linux.misc)
  • Re: compressed textures
    ... often improves performance because less data is required in the texture caches. ... Some older h/w has some precision problems with DXT1, but almost all modern cards support DXTn and typically have better precision. ... However, all the cards of the past few years have had good support for compressed textures, and even integrated chipsets support them, so you shouldn't have any problem requiring such support. ...
    (microsoft.public.win32.programmer.directx.graphics)