Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!ucbvax!YALE.ARPA!LEICHTER-JERRY From: LEICHTER-JERRY@YALE.ARPA.UUCP Newsgroups: mod.computers.vax Subject: main() and entry points in C Message-ID: <8606180820.AA08276@ucbvax.Berkeley.EDU> Date: Wed, 18-Jun-86 05:23:04 EDT Article-I.D.: ucbvax.8606180820.AA08276 Posted: Wed Jun 18 05:23:04 1986 Date-Received: Fri, 20-Jun-86 00:10:48 EDT Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: Organization: The ARPA Internet Lines: 84 Approved: info-vax@sri-kl.arpa Reply-To: >The use of this "first function will be transfer address" feature should >probably be avoided - it's non-portable (though I'd guess it's in VAX C >exactly because other implementations did this - Unix is one, in fact - >and programs came to rely on it. > -- Jerry Don't badmouth UNIX so quickly. Here's what happens in SysV: $ cat foo.c foo() { printf("hello, world!\n"); } $ cc -o foo foo.c undefined first referenced symbol in file main /lib/crt0.o ld fatal: Symbol referencing errors. No output written to foo The interpretation of this is that the UNIX linker was looking for a main() to satisfy the reference by the startup routines contained in the object module /lib/crt0.o (there is a _start() routine in /lib/crt0.o which the linker treats as a hardwired "transfer address" and which calls main()). The linker did not find main() so it barfed. Simple, no? When I discovered that VAX C made the first routine the entry point by default, I figured there was SOME reason for going to the trouble, so I pulled out my 4.2bsd documentation and checked out ld. It says this: [In the command description] The entry point of the output is the beginning of the first routine (unless the -e option is specified). [The description of -e] The following argument is taken to be the name of the entry point of the loaded program; location 0 is the default. Note that these two statements are not obviously consistent, and, in fact, had better disagree on any system without something like separate I&D spaces (else the "first routine" would have to be at 0, hence its address would be at 0 - but that's NULL!) Nor do they account for main(). I see no reference at all to _start(). Since you mentioned System V, I checked some AT&T 3B2 ld documentation I have here. The only references to the entry point are as follows: [The description of -e epsym]: Set the default entry point address for the output file to be that of symbol epsym. [Under Caveats] When the link editor is called through cc(1), a startup routine is linked with the user's program. [The startup routine arranges to call exit(), etc.; no mention of entry points.] Again, no reference to _start() - or to what the entry point would be if -e were left out. The documentation of the cc command doesn't say either. But note that your "simple" example, and hardwired entry point, are apparently NOT ld's doing, but cc's! At this point, I got curious to see what the reality of the situation was. So I tried your little foo program out on our local Celerity (4.2bsd). "cc foo" produces "Undefined: _main", and running the resulting a.out produces an immediate "Invalid address". However, a foo.o gets left around. So I did an "ld foo.o". This led to "Undefined: _printf". Well, getting there. I tried "ld foo.o /lib/libc.a". No errors! Running a.out produces "Hello world", followed by an access violation. Adding an explict exit(0) fixes that nicely. In fact, the resulting program even receives its command line arguments properly! (Well, it gets argc; I didn't bother to check argv, but it's pretty certain to be correct - both are coming from the Shell's exec.) My 3B2 is down at the moment so I have no System V implementation to try it on, but are you still going to bet that the first routine WON'T end up as the entry point? The thing that's so wonderful about Unix is its portability. And consisten- cy. And documentation. And, of course, the legions of Unix users who can be counted on to view ANY non-laudatory mention of Unix as "badmouthing" it. How is the comment - right or wrong - that Unix makes the default entry point the first routine "badmouthing" Unix? At worst, I was claiming that a lot of non-portable C code got written under Unix (since K&R certainly contains nothing to indicate that there can be an entry point other than main()). And if you don't believe THAT, then you haven't looked at much Unix code. -- Jerry -------