468,771 Members | 1,783 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,771 developers. It's quick & easy.

int main(void) { return main(); }

Is that in the object line a conforming program?
If so, why?
If not, why?
I'd expect it to be much like
int main(void)
{
for (;;);
}

But if I compile it with lcc-win32 and run it in its rundos.exe, it says the
program exits with a return value of -1073741819 (i.e. -2^30 + 5) after
0.032 seconds or so. Why?

--
#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
}
Mar 29 '07 #1
37 3142
Army1987 wrote On 03/29/07 14:31,:
Is that in the object line a conforming program?
You mean "subject" line, and it's a bad place for
questions.
If so, why?
Because it satisfies the definition of "conforming
program" in Section 4, paragraph 7.
If not, why?
See above.
I'd expect it to be much like
int main(void)
{
for (;;);
}

But if I compile it with lcc-win32 and run it in its rundos.exe, it says the
program exits with a return value of -1073741819 (i.e. -2^30 + 5) after
0.032 seconds or so. Why?
Probably because the program exceeded an implementation
limit. Which limit? The Standard doesn't say, but the lists
in Section 5.2.4 do not claim to be exhaustive. (See also
Section 1, paragraph 2, point 5).

--
Er*********@sun.com
Mar 29 '07 #2
On Mar 29, 11:31 am, "Army1987" <please....@for.itwrote:
Is that in the object line a conforming program?
If so, why?
If not, why?
I'd expect it to be much like
int main(void)
{
for (;;);

}

But if I compile it with lcc-win32 and run it in its rundos.exe, it says the
program exits with a return value of -1073741819 (i.e. -2^30 + 5) after
0.032 seconds or so. Why?

--
#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;

}
Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.

Mar 29 '07 #3
On Mar 29, 3:11 pm, "user923005" <dcor...@connx.comwrote:
On Mar 29, 11:31 am, "Army1987" <please....@for.itwrote:
Is that in the object line a conforming program?
If so, why?
If not, why?
I'd expect it to be much like
int main(void)
{
for (;;);
}
But if I compile it with lcc-win32 and run it in its rundos.exe, it says the
program exits with a return value of -1073741819 (i.e. -2^30 + 5) after
0.032 seconds or so. Why?
--
#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
}

Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.
It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever that is
wrt CLC <wink>) forcibly terminated the program.

To the OP: My bet is that, if you dig deep enough, you will find some
documentation on returncodes that tells you how to determine what a
"return value of -1073741819" actually means, and that documentation
will lead you to a "memory exhausted" error termination.

HTH
--
Lew
Mar 29 '07 #4

"Lew Pitcher" <lp******@sympatico.caha scritto nel messaggio
news:11*********************@y66g2000hsf.googlegro ups.com...
>Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.

It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever that is
wrt CLC <wink>) forcibly terminated the program.
I guess he was referring to the program in the object line, not to that in
the signature.

<ot>
BTW, I tried something very similar to that (signature) on a terminal logged
on a workstation (running on CentOS) at university, and in a short time it
raised an exception such as "Panic in 5 seconds" or something like that,
crashing the server and receiving curses from the other users who were
logged. A professor was sent to reboot the server as nobody else knew where
it was physically located. (Actually, I didn't expect that the OS *actually*
permitted me to do so rather than killing the process or making the malloc
return NULL. Taking into account that I didn't even have root privileges...)
On my PC, on Linux, if dim is small (i.e. below 2^15 or so) it makes the
system slow down more and more, and on a system monitor it seems that *all*
or almost RAM and swap partition are used, then the process is killed and
the memory released. Instead, if dim is large (2^16 or more), it prints an
unrealistic resullt of almost 3GB ("unrealistic" because I have 1 GB of RAM
and 1 GB of swap space) after less than a second. On Windows, a small dim
does apparently nothing different than for(;;); (but maybe I wasn't patient
enough), and a large dim prints a result of almost 2 GB.
</ot>
Mar 29 '07 #5

"Eric Sosman" <Er*********@sun.comha scritto nel messaggio
news:1175194998.166564@news1nwk...
Probably because the program exceeded an implementation
limit. Which limit? The Standard doesn't say, but the lists
in Section 5.2.4 do not claim to be exhaustive. (See also
Section 1, paragraph 2, point 5).
This means that I could write a compiler which doesn't support more than n
nested function calls, with n = 1 (that'd mean that you couldn't call any
function from within main...), and still call that a conforming
implementation? ;-)
Mar 29 '07 #6
Army1987 <pl********@for.itwrote:
>This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)
Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?

-Beej

Mar 29 '07 #7
On Mar 29, 2:39 pm, Beej Jorgensen <b...@beej.uswrote:
Army1987 <please....@for.itwrote:
This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)

Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?

-Beej
Perhaps it can be inferred from:

"5.2.4.1 Translation limits

[#1] The implementation shall be able to translate and
execute at least one program that contains at least one
instance of every one of the following limits:12)

-- 127 nesting levels of blocks"

Since each function call must necessarily enter a new block.

Mar 29 '07 #8
Beej Jorgensen wrote On 03/29/07 17:39,:
Army1987 <pl********@for.itwrote:
>>This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)


Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?
It's not there. One difficulty, I imagine, is in coming
up with an architecture-neutral way to describe the "weight"
of a function invocation. On many implementations it is
significantly cheaper to call a void function of one simple
argument that uses two auto variables than to call a struct-
valued function of forty arguments using ninety auto variables,
several of them being three-dimensional VLAs. But how do you
express that cost in a way that leads to a prescription of how
many nesting levels are usable?

--
Er*********@sun.com
Mar 29 '07 #9
"user923005" <dc*****@connx.comwrites:
On Mar 29, 2:39 pm, Beej Jorgensen <b...@beej.uswrote:
>Army1987 <please....@for.itwrote:
>This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)

Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?

-Beej

Perhaps it can be inferred from:

"5.2.4.1 Translation limits

[#1] The implementation shall be able to translate and
execute at least one program that contains at least one
instance of every one of the following limits:12)

-- 127 nesting levels of blocks"

Since each function call must necessarily enter a new block.
I don't think so. I think that refers to the number of physically
nested blocks in the source program, not to the depth during
execution.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 29 '07 #10
Eric Sosman <Er*********@sun.comwrites:
Beej Jorgensen wrote On 03/29/07 17:39,:
>Army1987 <pl********@for.itwrote:
>>>This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)

Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?

It's not there. One difficulty, I imagine, is in coming
up with an architecture-neutral way to describe the "weight"
of a function invocation. On many implementations it is
significantly cheaper to call a void function of one simple
argument that uses two auto variables than to call a struct-
valued function of forty arguments using ninety auto variables,
several of them being three-dimensional VLAs. But how do you
express that cost in a way that leads to a prescription of how
many nesting levels are usable?
By adding the following to C99 5.2.4.1:

-- 127 nesting levels of function calls

But all the limits in 5.2.4.1 are primarily translation-time limits;
an implementation that failed to meet one of them would probably do so
by blowing up during compilation. The closest thing to a run-time
limit is 65535 bytes in an object, and even that is something that the
compiler has too keep track of during compilation (except for
dynamically allocated objects).

A required minimum number of nested function calls, on the other hand,
would be something that would only affect program execution, and it
would depend on the resources available during program execution.

Perhaps there should be a separate set of required limits for run-time
capacity.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 29 '07 #11
Keith Thompson wrote:
Eric Sosman <Er*********@sun.comwrites:
>Beej Jorgensen wrote On 03/29/07 17:39,:
>>Army1987 <pl********@for.itwrote:

This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)
Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?
It's not there. One difficulty, I imagine, is in coming
up with an architecture-neutral way to describe the "weight"
of a function invocation. On many implementations it is
significantly cheaper to call a void function of one simple
argument that uses two auto variables than to call a struct-
valued function of forty arguments using ninety auto variables,
several of them being three-dimensional VLAs. But how do you
express that cost in a way that leads to a prescription of how
many nesting levels are usable?

By adding the following to C99 5.2.4.1:

-- 127 nesting levels of function calls
... which expresses a requirement for nesting levels, but
completely ignores the "weight" or "cost" of a call.

int f(int depth) {
char broiled[65535] = { 0 };
char ming[65535] = { 1 };
char shu_ding[65535] = { 2 };
... about fifty MB worth of auto variables ...
return (depth <= 126) ? 42
: broiled[f(depth+1)%65535]
+ ming[f(depth+2)%65535]
+ shu_ding[f(depth+3)%65535]
+ ... ;
}

It seems to me that an implementation that guaranteed correct
evaluation of foo(0) might be able to guarantee little else ...
Perhaps there should be a separate set of required limits for run-time
capacity.
Perhaps. But (I repeat) see Section 1, paragraph 2, point 5.

--
Eric Sosman
es*****@acm-dot-org.invalid

Mar 30 '07 #12
Eric Sosman <es*****@acm-dot-org.invalidwrites:
Keith Thompson wrote:
>Eric Sosman <Er*********@sun.comwrites:
>>Beej Jorgensen wrote On 03/29/07 17:39,:
Army1987 <pl********@for.itwrote:
This means that I could write a compiler which doesn't support more
than n nested function calls, with n = 1 (that'd mean that you couldn't
call any function from within main...), and still call that a
conforming implementation? ;-)
Even though I can't see that it's strictly against the standard, that
implementation would certainly violate the spirit of c99 6.5.2.2p11:

# Recursive function calls shall be permitted, both directly and
# indirectly through any chain of other functions.

I was a little surprised to not see a minimum limit on the function call
depth, though. Am I just missing it?
It's not there. One difficulty, I imagine, is in coming
up with an architecture-neutral way to describe the "weight"
of a function invocation. On many implementations it is
significantly cheaper to call a void function of one simple
argument that uses two auto variables than to call a struct-
valued function of forty arguments using ninety auto variables,
several of them being three-dimensional VLAs. But how do you
express that cost in a way that leads to a prescription of how
many nesting levels are usable?
By adding the following to C99 5.2.4.1:
-- 127 nesting levels of function calls

... which expresses a requirement for nesting levels, but
completely ignores the "weight" or "cost" of a call.
[snip]

Yes, it does. I can't think of any good way to express such a
requirement; the point would be to require the implementation to
accept *some* program that produces 127 levels of function calls.
(BTW, the wording could be clearer; it's intended to refer to the
depth of the "call stack", not to something like
f1(f2(f3(f4(...f127()...)))).)

I think main point of the translation limits in 5.2.4.1 isn't so much
to require those specific values (though that's part of it), but to
discourage imposing specific limits at all. For example, a compiler
must support (at least one program that contains) at least 127
arguments in one function call. The easiest way to satisfy that
requirement isn't to use a fixed-size 127-element table; it's to
handle arguments dynamically, limiting them only by amount of memory
available during compilation.

A requirement to allow 127 levels of function calls, if it were added
to the standard, would forbid an implementation that only allows 1
level.
It seems to me that an implementation that guaranteed correct
evaluation of foo(0) might be able to guarantee little else ...
>Perhaps there should be a separate set of required limits for run-time
capacity.

Perhaps. But (I repeat) see Section 1, paragraph 2, point 5.
Which says:

This International Standard does not specify
[...]
-- the size or complexity of a program and its data that will
exceed the capacity of any specific data-processing system or
the capacity of a particular processor

And yet it requires a hosted implementation to support 65535 bytes in
an object.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 30 '07 #13
Lew Pitcher wrote:
On Mar 29, 3:11 pm, "user923005" <dcor...@connx.comwrote:
>On Mar 29, 11:31 am, "Army1987" <please....@for.itwrote:
.... snip ...
>>
>>But if I compile it with lcc-win32 and run it in its rundos.exe,
it says the program exits with a return value of -1073741819
(i.e. -2^30 + 5) after 0.032 seconds or so. Why?

#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
}

Eric answered your question, and I have a guess about the why
part. Probably, since each call has to store the return address,
you ran out of automatic storage.

It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever
that is wrt CLC <wink>) forcibly terminated the program.
No forcible termination. It just ended, and due to the abysmally
stupid failure to return a valid value from main the result is
undefined.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 30 '07 #14
On Mar 29, 9:50 pm, CBFalconer <cbfalco...@yahoo.comwrote:
Lew Pitcher wrote:
On Mar 29, 3:11 pm, "user923005" <dcor...@connx.comwrote:
On Mar 29, 11:31 am, "Army1987" <please....@for.itwrote:

... snip ...
>But if I compile it with lcc-win32 and run it in its rundos.exe,
it says the program exits with a return value of -1073741819
(i.e. -2^30 + 5) after 0.032 seconds or so. Why?
>#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
^
Lookee here----------------------/
>}
Eric answered your question, and I have a guess about the why
part. Probably, since each call has to store the return address,
you ran out of automatic storage.
It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever
that is wrt CLC <wink>) forcibly terminated the program.

No forcible termination. It just ended, and due to the abysmally
stupid failure to return a valid value from main the result is
undefined.
Chuck, it appears that you didn't notice the
return 0;
in the OPs code for main()

I didn't see any way for the code to avoid that statement, so it
appears that main() /does/ return a valid value.

--
Lew

Mar 30 '07 #15
At about the time of 3/29/2007 11:31 AM, Army1987 stated the following:
Is that in the object line a conforming program?
If so, why?
If not, why?
I'd expect it to be much like
int main(void)
{
for (;;);
}
The above questions have already been answered by another poster, so
I'll leave that part of it alone.
>
But if I compile it with lcc-win32 and run it in its rundos.exe, it says the
program exits with a return value of -1073741819 (i.e. -2^30 + 5) after
0.032 seconds or so. Why?
It's probably undefined behavior which means that it's implementation
specific. FWIW, on my system, the program ran until I got a memory
fault and the core dropped.

strata:/home/dr2867/c/test 1051 $$$ ->./ub003
Memory fault (core dumped)
strata:/home/dr2867/c/test 1052 $$$ ->ls -l
total 69586
-rwxr-xr-x 1 dr2867 users 7195 Mar 29 21:29 ub003
-rw-r--r-- 1 dr2867 users 47 Mar 29 21:28 ub003.c
-rw------- 1 dr2867 users 67309568 Mar 29 21:29 ub003.core
strata:/home/dr2867/c/test 1052 $$$ ->

The program that you gave:

int main(void) { return main(); }

is an infinite recursive loop. It will run until the stack blows up.
Which is what happened in my case. As to why you got a return value,
that's implementation specific: aka undefined behavior.
--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 30 '07 #16
At about the time of 3/29/2007 12:52 PM, Army1987 stated the following:
"Lew Pitcher" <lp******@sympatico.caha scritto nel messaggio
news:11*********************@y66g2000hsf.googlegro ups.com...
>>Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.
It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever that is
wrt CLC <wink>) forcibly terminated the program.

I guess he was referring to the program in the object line, not to that in
the signature.

<ot>
BTW, I tried something very similar to that (signature) on a terminal logged
on a workstation (running on CentOS) at university, and in a short time it
raised an exception such as "Panic in 5 seconds" or something like that,
crashing the server and receiving curses from the other users who were
logged. A professor was sent to reboot the server as nobody else knew where
it was physically located. (Actually, I didn't expect that the OS *actually*
permitted me to do so rather than killing the process or making the malloc
return NULL. Taking into account that I didn't even have root privileges...)
LOL

What was the fallout from that? Considering that you weren't even root,
did they know it was you who did it?

Most modern operating systems that use memory protection are protected
enough so if a program goes out of control, the OS kills it in short
order. Even programs ran under UID 0 (root) can't really crash the
system on their own. Now something like

dd if=/dev/random of=dev/kmem bs=1024

will kill the system in short order.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 30 '07 #17
At about the time of 3/29/2007 4:20 PM, Keith Thompson stated the following:
Eric Sosman <Er*********@sun.comwrites:
> It's not there. One difficulty, I imagine, is in coming
up with an architecture-neutral way to describe the "weight"
of a function invocation. On many implementations it is
significantly cheaper to call a void function of one simple
argument that uses two auto variables than to call a struct-
valued function of forty arguments using ninety auto variables,
several of them being three-dimensional VLAs. But how do you
express that cost in a way that leads to a prescription of how
many nesting levels are usable?

By adding the following to C99 5.2.4.1:

-- 127 nesting levels of function calls

But all the limits in 5.2.4.1 are primarily translation-time limits;
an implementation that failed to meet one of them would probably do so
by blowing up during compilation. The closest thing to a run-time
limit is 65535 bytes in an object, and even that is something that the
compiler has too keep track of during compilation (except for
dynamically allocated objects).

A required minimum number of nested function calls, on the other hand,
would be something that would only affect program execution, and it
would depend on the resources available during program execution.
Exactly.
Perhaps there should be a separate set of required limits for run-time
capacity.
Um...no.

How are you going to account for a program that runs on a super
computer? One that uses 25GB Ram, 50 CPUs, and other resources? You
can't. A program cannot use more resources than the system has
available, period. Eventually, you will run out of something...disk
space, memory, CPU utilization, Network bandwidth, etc. Even swap is
only so big. IMO, system imposed resource limits are good way to go.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 30 '07 #18
Lew Pitcher wrote:
On Mar 29, 9:50 pm, CBFalconer <cbfalco...@yahoo.comwrote:
>Lew Pitcher wrote:
>>On Mar 29, 3:11 pm, "user923005" <dcor...@connx.comwrote:
On Mar 29, 11:31 am, "Army1987" <please....@for.itwrote:

... snip ...
>>>>But if I compile it with lcc-win32 and run it in its rundos.exe,
it says the program exits with a return value of -1073741819
(i.e. -2^30 + 5) after 0.032 seconds or so. Why?
>>>>#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
^
Lookee here----------------------/
>>>>}
>>>Eric answered your question, and I have a guess about the why
part. Probably, since each call has to store the return address,
you ran out of automatic storage.
>>It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever
that is wrt CLC <wink>) forcibly terminated the program.

No forcible termination. It just ended, and due to the abysmally
stupid failure to return a valid value from main the result is
undefined.

Chuck, it appears that you didn't notice the
return 0;
in the OPs code for main()

I didn't see any way for the code to avoid that statement, so it
appears that main() /does/ return a valid value.
Woops. My second mistake this year. Things are getting bad.

That leaves something foolish in lcc-win32.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 30 '07 #19
On Thu, 29 Mar 2007 21:29:19 -0700, Daniel Rudy
<sp******@spamthis.netwrote:
>dd if=/dev/random of=dev/kmem bs=1024
"'dd' is not recognized as an internal or external command,
operable program or batch file."

Jim
Mar 30 '07 #20
On Fri, 30 Mar 2007 04:18:34 GMT, Daniel Rudy <sp******@spamthis.net>
wrote:
>The program that you gave:

int main(void) { return main(); }

is an infinite recursive loop. It will run until the stack blows up.
Which is what happened in my case. As to why you got a return value,
that's implementation specific: aka undefined behavior.
What's a stack? Where's that in the C standard?

Jim
Mar 30 '07 #21
Daniel Rudy wrote:
The program that you gave:

int main(void) { return main(); }

is an infinite recursive loop. It will run until the stack blows up.
Or until your patience runs out: it's tail-recursive and a compiler
can optimise it into a spin loop.

--
SpinDizzy Hedgehog
The "good old days" used to be much better.

Mar 30 '07 #22
Daniel Rudy <sp******@spamthis.netwrites:
At about the time of 3/29/2007 4:20 PM, Keith Thompson stated the following:
[...]
>Perhaps there should be a separate set of required limits for run-time
capacity.

Um...no.

How are you going to account for a program that runs on a super
computer? One that uses 25GB Ram, 50 CPUs, and other resources? You
can't. A program cannot use more resources than the system has
available, period. Eventually, you will run out of something...disk
space, memory, CPU utilization, Network bandwidth, etc. Even swap is
only so big. IMO, system imposed resource limits are good way to go.
That's not what I meant. I'm not suggesting that an implementation
must impose a specific limit. I'm suggesting that an implementation
must support *at least* a specified depth of function calls.

Take a look at C99 5.2.4.1. One of the listed requirements is that an
implementation must be able to translate and execute at least one
program with 127 nesting levels of blocks. The actual limit imposed
by an implementation can be much higher than that.

Similarly, I'm suggesting that a requirement *could* be added saying
that an implementation must support at least, say, 127 nested function
calls at run time; the actual limit, if any, could be much higher.

I'm not necessarily saying that such a change to the standard would be
a good idea; I was just saying that it *could* be done.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 30 '07 #23

JimS wrote:
On Thu, 29 Mar 2007 21:29:19 -0700, Daniel Rudy
<sp******@spamthis.netwrote:
dd if=/dev/random of=dev/kmem bs=1024

"'dd' is not recognized as an internal or external command,
operable program or batch file."
That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.

Mar 30 '07 #24

"Daniel Rudy" <sp******@spamthis.netha scritto nel messaggio
news:qm***************@newssvr17.news.prodigy.net. ..
At about the time of 3/29/2007 12:52 PM, Army1987 stated the following:
>"Lew Pitcher" <lp******@sympatico.caha scritto nel messaggio
news:11*********************@y66g2000hsf.googlegr oups.com...
>>>Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.
It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever that is
wrt CLC <wink>) forcibly terminated the program.

I guess he was referring to the program in the object line, not to that
in
the signature.

<ot>
BTW, I tried something very similar to that (signature) on a terminal
logged
on a workstation (running on CentOS) at university, and in a short time
it
raised an exception such as "Panic in 5 seconds" or something like that,
crashing the server and receiving curses from the other users who were
logged. A professor was sent to reboot the server as nobody else knew
where
it was physically located. (Actually, I didn't expect that the OS
*actually*
permitted me to do so rather than killing the process or making the
malloc
return NULL. Taking into account that I didn't even have root
privileges...)

LOL

What was the fallout from that? Considering that you weren't even root,
did they know it was you who did it?
Nothing, fortunately nobody was working on anything serious on that server,
they were mostly just surfing on the Web or writing simple homework
programs.
Anyway, as soon as I realized what I did, I apoligized. (Again, I didn't
expect *that* to actually happen...)
Mar 30 '07 #25
santosh wrote:
That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.
LOL!

To the OP. The program in the subject line gives "Segmentation Fault".
Running it with "strace" on Kubuntu 6.10 shows how it faults at first
loop(imho). The second program eat each byte of available memory, both ram
and swap, and is killed by the system:

emanuele@engine:~$ ./strange
Killed

What happens on Windows?

Bye, Emanuele
--
Linux engine 2.6.17-11-generic i686 GNU/Linux
Mar 30 '07 #26
>I didn't see any way for the code to avoid that statement, so it
>appears that main() /does/ return a valid value.

Woops. My second mistake this year. Things are getting bad.
Don't worry. Pay back your sleep debt and you'll be fine.
That leaves something foolish in lcc-win32.
The program which gives an absurd return value on lcc-win32 (as shown by
rundos.exe, which executes a program and then prints the return value of
main() and the time elapsed) is the one in the *object line*:
int main(void)
{
return main();
}

If I understand correctly, as soon as the stack (or whatever you call it) is
full the program exits with an implementation defined return value.
(With gcc, it just dumps core).

Sorry if the <newline><newline>--<newlinesequence wasn't enough to show
the second program was a signature. It does 'work' if dim is large enough
(and, with lcc-win32, it gives a return value of 0). The unrealistic result
I was refering to was that printed by printf, which is larger than the
memory available on my PC. Probably malloc is implemented as described in
http://c-faq.com/malloc/lazyalloc.html only if dim is very large, but that's
another story.
Mar 30 '07 #27

"JimS" <so***@not.comha scritto nel messaggio
news:lb********************************@4ax.com...
What's a stack? Where's that in the C standard?
The fact that the C standard doesn't define a name for "the area of memory
where automatic variables are stored" doesn't mean that we are forbidden to
use an already existing English word to refer to that, right?
Mar 30 '07 #28
Army1987 wrote:
>
"JimS" <so***@not.comha scritto nel messaggio
news:lb********************************@4ax.com...
>What's a stack? Where's that in the C standard?

The fact that the C standard doesn't define a name for "the area of memory
where automatic variables are stored" doesn't mean that we are forbidden
to use an already existing English word to refer to that, right?
So long as you remember that not all automatic variables are
stored on the stack [1], and that the usual implication of
"the stack" is a single contiguous area of memory that grows
and shrinks from one end -- and the C area-for-automatics isn't
required to do that, and at least one implementation I know
of doesn't either; IIRC chunks of stack are allocated from
the heap as needed, and deallocated when un-needed, and those
chunks can be discontiguous and in essentially random order.

So yes, if you're happy using `stack` to mean `that collection
of memory chunks in random order, allocated and decallocated
on demand, used for some automatic variables and maybe some
return addresses`, then fine, but it'll be such a palaver
stressing that each post you use it that it'd be easier to
go with the flow: C doesn't have "a stack", although some
(many) implementations use one, and some of those use the
stack-thingy that goes with the machine architecture too.

Remembering that C has no stack means it's easy to answer
some paying-excessive-attention-to-implementation-details,
like "does the C stack grow up or down?": C doesn't have a
stack, so the answer is "No". (As you know, Bob, stacks
always grow down, because you add new items to the top and
the remaining items are pushed -- hence the name -- further
down. Stacks can't "grow up": if you tried, all the plates
would fall out.)

[1] Not as such, although of course they may get /saved/ there.

--
Lunchtime Hedgehog
The "good old days" used to be much better.

Mar 30 '07 #29

"Manuel T" <ma****@t.govwrote in message news:eu**********@tdi.cu.mi.it...
santosh wrote:
>That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.

LOL!

To the OP. The program in the subject line gives "Segmentation Fault".
Running it with "strace" on Kubuntu 6.10 shows how it faults at first
loop(imho). The second program eat each byte of available memory, both ram
and swap, and is killed by the system:

emanuele@engine:~$ ./strange
Killed

What happens on Windows?
On XP compiled with default options with either my version of
gcc or bcc 5.02 it runs tens of thousands of loops and exits.
The shell shows an error code of 5. Compiled with -O2 both
compilers produce and infinite loop.
Mar 30 '07 #30

"Barry" <ba****@nullhighstream.netwrote in message
news:13*************@corp.supernews.com...
>
"Manuel T" <ma****@t.govwrote in message
news:eu**********@tdi.cu.mi.it...
>santosh wrote:
>>That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.

LOL!

To the OP. The program in the subject line gives "Segmentation Fault".
Running it with "strace" on Kubuntu 6.10 shows how it faults at first
loop(imho). The second program eat each byte of available memory, both
ram
and swap, and is killed by the system:

emanuele@engine:~$ ./strange
Killed

What happens on Windows?

On XP compiled with default options with either my version of
gcc or bcc 5.02 it runs tens of thousands of loops and exits.
The shell shows an error code of 5. Compiled with -O2 both
compilers produce and infinite loop.
Oops, scratch that, with O2 the Borland compiler just runs
a while longer.
Mar 30 '07 #31
At about the time of 3/30/2007 1:37 AM, Keith Thompson stated the following:
Daniel Rudy <sp******@spamthis.netwrites:
>At about the time of 3/29/2007 4:20 PM, Keith Thompson stated the following:
[...]
>>Perhaps there should be a separate set of required limits for run-time
capacity.
Um...no.

How are you going to account for a program that runs on a super
computer? One that uses 25GB Ram, 50 CPUs, and other resources? You
can't. A program cannot use more resources than the system has
available, period. Eventually, you will run out of something...disk
space, memory, CPU utilization, Network bandwidth, etc. Even swap is
only so big. IMO, system imposed resource limits are good way to go.

That's not what I meant. I'm not suggesting that an implementation
must impose a specific limit. I'm suggesting that an implementation
must support *at least* a specified depth of function calls.
Ah, ok. Thanks for clearing that up.
Take a look at C99 5.2.4.1. One of the listed requirements is that an
implementation must be able to translate and execute at least one
program with 127 nesting levels of blocks. The actual limit imposed
by an implementation can be much higher than that.

Similarly, I'm suggesting that a requirement *could* be added saying
that an implementation must support at least, say, 127 nested function
calls at run time; the actual limit, if any, could be much higher.

I'm not necessarily saying that such a change to the standard would be
a good idea; I was just saying that it *could* be done.
I still personally think that system imposed limits are the best way to
go. I did take a look at n1124 (downloaded it off the net in fact) and
I see exactly what you are talking about. And my point was footnote 13
which says "13) Implementations should avoid imposing fixed translation
limits whenever possible." which I interpret to mean that the system
should impose the limits.

So I guess that we both agree then.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 31 '07 #32
At about the time of 3/30/2007 1:48 AM, santosh stated the following:
JimS wrote:
>On Thu, 29 Mar 2007 21:29:19 -0700, Daniel Rudy
<sp******@spamthis.netwrote:
>>dd if=/dev/random of=dev/kmem bs=1024
"'dd' is not recognized as an internal or external command,
operable program or batch file."

That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.
That is so true.

Speaking of which...

http://www.rebelz.net/gallery/v/fun/...WinXP.jpg.html
--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 31 '07 #33
At about the time of 3/30/2007 3:19 AM, Army1987 stated the following:
"Daniel Rudy" <sp******@spamthis.netha scritto nel messaggio
news:qm***************@newssvr17.news.prodigy.net. ..
>At about the time of 3/29/2007 12:52 PM, Army1987 stated the following:
>>"Lew Pitcher" <lp******@sympatico.caha scritto nel messaggio
news:11*********************@y66g2000hsf.googleg roups.com...
Eric answered your question, and I have a guess about the why part.
Probably, since each call has to store the return address, you ran out
of automatic storage.
It is more likely that the loop
for (i=0; malloc(dim); i++) /*nothing*/ ;
exhausted available 'heap' memory, and the system (what-ever that is
wrt CLC <wink>) forcibly terminated the program.
I guess he was referring to the program in the object line, not to that
in
the signature.

<ot>
BTW, I tried something very similar to that (signature) on a terminal
logged
on a workstation (running on CentOS) at university, and in a short time
it
raised an exception such as "Panic in 5 seconds" or something like that,
crashing the server and receiving curses from the other users who were
logged. A professor was sent to reboot the server as nobody else knew
where
it was physically located. (Actually, I didn't expect that the OS
*actually*
permitted me to do so rather than killing the process or making the
malloc
return NULL. Taking into account that I didn't even have root
privileges...)
LOL

What was the fallout from that? Considering that you weren't even root,
did they know it was you who did it?

Nothing, fortunately nobody was working on anything serious on that server,
they were mostly just surfing on the Web or writing simple homework
programs.
Anyway, as soon as I realized what I did, I apoligized. (Again, I didn't
expect *that* to actually happen...)

Well, it's good to know that all's well that ends well.
--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 31 '07 #34
At about the time of 3/29/2007 10:52 PM, JimS stated the following:
On Fri, 30 Mar 2007 04:18:34 GMT, Daniel Rudy <sp******@spamthis.net>
wrote:
>The program that you gave:

int main(void) { return main(); }

is an infinite recursive loop. It will run until the stack blows up.
Which is what happened in my case. As to why you got a return value,
that's implementation specific: aka undefined behavior.

What's a stack? Where's that in the C standard?

Jim
It's not, but judging from the computers in use today, it's a reasonable
assumption. As for your first question, you are joking, right?
--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 31 '07 #35
Daniel Rudy said:
At about the time of 3/29/2007 10:52 PM, JimS stated the following:
>On Fri, 30 Mar 2007 04:18:34 GMT, Daniel Rudy <sp******@spamthis.net>
wrote:
>>The program that you gave:

int main(void) { return main(); }

is an infinite recursive loop. It will run until the stack blows
up.
Which is what happened in my case. As to why you got a return
value, that's implementation specific: aka undefined behavior.

What's a stack? Where's that in the C standard?

Jim

It's not, but judging from the computers in use today, it's a
reasonable
assumption. As for your first question, you are joking, right?
Here's a stack:

void push(unsigned char c); /* stick this in a header */
unsigned char pop(void); /* and this */

static unsigned char stack[6] = {0};
static unsigned int stackptr = 0;

void push(unsigned char c)
{
if(stackptr < 6)
{
char[stackptr++] = c;
}
}

unsigned char pop(void)
{
unsigned char c = 0;
if(stackptr 0)
{
c = char[--stackptr];
}
return c;
}

I don't quite see what this has to do with recursive functions.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 31 '07 #36
On 31 Mar, 19:11, Daniel Rudy <spamt...@spamthis.netwrote:
That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.

That is so true.

Speaking of which...

http://www.rebelz.net/gallery/v/fun/...WinXP.jpg.html
LOL... Is it real? (I fear it is.)

Apr 1 '07 #37
At about the time of 4/1/2007 3:34 PM, ar******@email.it stated the
following:
On 31 Mar, 19:11, Daniel Rudy <spamt...@spamthis.netwrote:
>>That's an Unix command. For Windows, just launch iexplore.exe. A blue
screen future is inevitable.
That is so true.

Speaking of which...

http://www.rebelz.net/gallery/v/fun/...WinXP.jpg.html

LOL... Is it real? (I fear it is.)
Well, you see a busted CD in the floppy drive...
--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Apr 3 '07 #38

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by Frederick Ding | last post: by
6 posts views Thread by rahulsinner | last post: by
36 posts views Thread by x_knifer_x | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.