Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!gatech!bloom-beacon!think!ames!ptsfa!ihnp4!homxb!mtuxo!mtune!codas!cpsc6a!rtech!wrs!dg From: dg@wrs.UUCP (David Goodenough) Newsgroups: comp.lang.c Subject: Re: Accessing argc & argv from a function Message-ID: <253@wrs.UUCP> Date: Fri, 17-Jul-87 14:14:11 EDT Article-I.D.: wrs.253 Posted: Fri Jul 17 14:14:11 1987 Date-Received: Sun, 19-Jul-87 01:19:21 EDT References: <22@flmis06.ATT.COM> Reply-To: dg@wrs.UUCP (David Goodenough) Organization: Wind River Systems, Emeryville, CA Lines: 89 In article <22@flmis06.ATT.COM> mikel@flmis06.ATT.COM (Mikel Manitius) writes: >I recently ran accross an interresting question. > >How does one get at argc and argv (and possibly envp) from a function? >Without declaring it in main first, and then passing a pointer (global >or not)! Assume you don't have control over what happens in main. Can >you still get at the argument vector? >-- > Mikel Manitius @ AT&T Network Operations > mikel@codas.att.com.uucp | attmail!mikel In a sentence - you could, but it would be a real mess, and extremely system dependant. To show *EXACTLY* what happens, here is the stack (from a PDP-11, 68K, VAX, Z80, and probably 80*86) just after entry to main: | | | envp | <------ these are the ONLY +----------------+ <------ references to argc etc. that | argv | <------ exist in the memory space +----------------+ <------ of the program, so you've | argc | <------ GOT to use them or do without +----------------+ | return address | | from main | +----------------+ | previous stack | frame pointer ->| environment | +----------------+ | locals for | | main | Since argc, argv, and envp can only be accessed at this location, you have two options: get at them as arguments to main (nice and clean), or where ever it is you want them do something like: getargs() { int i; static int *ip; /* note the static */ static struct frame { char *return; struct frame *previous; } *fp; Now, since i is the only automatic local (this is the reason for ip & fp being static), ip = &i will set ip to point to one int below the current frame pointer. NOW fp = (struct frame *) &ip[1]; points fp at your current frame, and all you have to do is chase back up the stack till you find whatever it is you're looking for. NOTE that this is a kludge that I *DO NOT* recommend to anyone, because it will be so unportable as to give most programmers a nervous breakdown. Also I don't know how you'd set about detecting when you hit main. Once you do, something along the lines of: ip = (int *) fp; points ip back into the stack at main's locals (i.e. argc etc.) and indexing off ip can get you what you want. Not very pretty you'll agree :-). As an aside, I saw this used JUST ONCE in BCPL, which is a predecessor of C. It did work in that environment because BCPL runs with two stacks: one growing from high memory down contains constant sized frames, and another growing from low memory up holds the locals. As a result of this, chasing up the frame stack was not as traumatic as in C. P.S. this second suggestion is NOT meant to be taken too seriously, it is more an explanation of why you should simply try to get the stuff out of main: as you say either by passing parameters, or by using globals. As an aside, if you have source for the UNIX library look at getenv, because somehow or other it does about what you're after, and I'm damned if I know how it works. -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+