Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!ucsd!nosc!crash!nusdecs!rwhite From: rwhite@nusdecs.uucp (0257014-Robert White(140)) Newsgroups: comp.lang.c++ Subject: Re: Again: Access to argc,argv outside main() Message-ID: <1990Oct30.221009.10422@nusdecs.uucp> Date: 30 Oct 90 22:10:09 GMT References: <3129@zgdvda.zgdvda.uucp> Organization: National University San Diego Lines: 85 The primary problem you will expeirenc trying to access argc and argv is that they are standard refrences to a variable phenominon. The independant variable being the operating system, the dependant variable being the compiler library, and the outcome only being garenteed at a single point... the invocation of main. In C the initalization sequence is basically (no flames please): 1. True Static data. This is usually part of the load image. 2. Procedural Startup Code. Provided by the compiler/library. 3. Invocation of _main(). It should be aparent that the presence of arguments to main would be established durring the invocation step (as with any C function call) and there is no comentary as to how the data needs must be represented prior to that time. It is obvious that the data does indeed exist prior to that time, but the shape of the data (argc, argv, and envp for some) is not necessarily useful. It is often unparsed or living in one or more system areas somewhere. And, as such it is most likely easier and maybe even best left alone until after the invocation of _main(). Generalizing this to C++, you are informed that the constructors of static objects, which are not always actual function-call events (if the constructor is just simple assignments the object may be converted to true static data and initalized by the module loader ??), will be 'called' "before the invocation of main." Given that a global instance of argc and argv are/should be in identical format to the real arguments (I guess on this one) I, as a theoretical compiler writer, would have left the invocation code for main alone except for the copying of the argc/argv into the global area. This, in turn implies that argc and argv do/will not ever be likely to exist in that form durring the constructors of static objects. Indeed there may not be an actual copy of the arguments at all. The stack frame for _main() is (by implication) garenteed to be "in scope" for the entire execution period of the program proper, and argc/argv may be refrences back into the real(tm) stack frame for _main(). You might be able to test this by assigning to the globals and then testing the locals (I don't know wether argc/argv are constant). Reguardless of the test, any system whare that is the case will, by definition, procribe the globals from existing durring the constructors because the stack fram where they would be put is occupied by the constructors frames themselves. REAL WAG (wild ass guess) HERE: cfront, because of the way it must produce "normal" C code, may replace your main function with a dummy main that calls the constructors and then calls the original (now name-munged) main(). You might be able to edit the C code so prodeuced to sneak the arguments to your constructor, but this would be a real pain to maintain. Obviously not an available practice on native-code C++ compilers. Your choices are feiw and simple (barring the wag): 1. Get and change the library code to make the globals exist before constructor calls. 2. Extract the args for the OS yourself. 3. Make a portable work-around. 4. (something I havn't thought of yet ;-) Number 3 is my best recomendation (at least until 4 comes around). I would suggest a static refrence class for the args which will fufill the minimum requirements of the other static objects and which you can backfill with the real(tm) arguments. (possibly even causing it to wander out and reinitalize the dependant static objects). Better yet, only declare static pointers to the requsite objects and put off *all* your now-so-called static objects until after main() is in scope, making main() a container function for: { initalizations(argc,argv); real_logic(argc,argv); cleanup(); } and move your current main() into real_logic(). (This is OOP after all). Really depends on your real need. Rob.