chris@mimsy.UUCP (Chris Torek) (12/19/87)
As various people have pointed out, crt0.c (the file in which the exit(main(argc, argv, env)) call was found) is a system dependent way of getting C code started. (When the operating system is asked to run a program, it jumps to some starting location with registers and/or stack set up in some particular way. The code at this start location has to turn this into a normal C stack frame and call main. In most Unixes, this is done by a routine in crt0.s or crt0.c.) Nonetheless, exit(main(argc, argv, env)) is a perfectly legal thing to write. Here is an example with the env parameter deleted: int main(argc, argv) int argc; char **argv; { int n; /* * Compute and print the factorial of all arguments. */ if (argc < 2) return (0); /* no arguments */ /* do the first argument */ n = atoi(argv[1]); printf("%d! = %d\n", n, fac(n)); /* do the rest of the arguments */ exit(main(argc - 1, argv + 1)); } int fac(n) int n; { if (n < 2) return (1); return (n * fac(n - 1)); } The *only* thing that is special about `main' is that the runtime system somehow calls it to start the program, and that when it returns to the runtime system (if ever), the `int' value it returns is given back to the system as a status value. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
djones@megatest.UUCP (Dave Jones) (12/23/87)
in article <2058@bloom-beacon.MIT.EDU>, wesommer@athena.mit.edu (William Sommerfeld) says:
GNU emacs has its own version of crt0.c (with probably hundreds of
#ifdefs to account for all sorts of machine dependancies) because it
has to be able to dump out a core image of itself containing
pre-loaded emacs lisp, and then restart this core image later.
It's quite possible to dump core without hacking crt0.c, which seems to
me to be an absolute no-no. (But then, I'm the guy who hacked exit().)
Must be some other reason for the special crt0.c in gnu-emacs.
-- djones
ok@quintus.UUCP (01/24/88)
In article <310@fig.bbn.com>, rsalz@bbn.com (Rich Salz) writes: > Nope. The use of && and || in csh is the opposite of that in /bin/sh. > /bin/sh -c "/bin/test -d foo || mkdir foo" > Means if the foo directory doesn't exist, make it. That is, /bin/sh does > the "conceptually right thing" in that it takes a||b to mean, do b if a > failed. > > The Cshell takes a||b in the mathematical sense; do b if a does an exit(0): > /bin/csh -c "/bin/test -d foo || mkdir foo" > will never make the directory, or mkdir will spit if it already exists. > If you have a C-shell, do the following: cat >foo <<'EOF' #!/bin/csh (exit $1) && (echo true) || (echo false) 'EOF' chmod +x foo foo 0 prints true foo 1 prints false which indicates that the C-shell ***IS*** treating && and || the way I said it does. I tried Rich Salz's specific example, and it ***DID*** make the directory. This was under SunOS 3.2. The C-shell manual explicitly says that "Pipelines that are separated by && or || form conditional sequences in which the execution of pipelines on the right depends upon the success or failure, respectively, of the pipeline on the left." So it would be a very serious bug if Rich Salz were right. The C-shell, in addition to commands, has EXPRESSIONS, and in expressions && and || do what he thinks. But *ONLY* in expressions. Unlike the Bourne shell, the C-shell doesn't have you use commands in if and while. You use *expressions* there. The {command} form converts a command to an expression, but mapping exit 0 to 1 and exit non-zero to 0. (It's in the manual.) Suppose you want to create directory foo if it doesn't exist and the current directory is writable. Four ways: sh : test -d foo || ( test -w . && mkdir foo ) sh : if test ! -d foo && test -w . then mkdir foo fi csh: test -d foo || ( test -w . && mkdir foo ) csh: if ( ! { test -d foo } && { test -w . } ) mkdir foo ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ these are expressions! Yes, it is confusing that the same operators are used with opposite meanings. Even so, it is wise to try one's examples before claiming that they don't work...
guy@gorodish.UUCP (01/24/88)
> Nope. The use of && and || in csh is the opposite of that in /bin/sh.
Nope. The use of && and ||, in versions of "csh" recent enough to have the bug
that broke && and || fixed, is the same as that in "/bin/sh". This includes
the 4.2 and 4.3 versions, and if I remember correctly it includes the 4.1
version as well. (The bug was caused by somebody working on the C shell
forgetting that a zero exit status means true, not false, and that a non-zero
exit status means false, not true.)
Guy Harris
{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
guy@sun.com