Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!lll-winken!decwrl!sgi!mips!rat!vlsisj!davidc From: davidc@vlsisj.uucp (David Chapman) Newsgroups: comp.unix.programmer Subject: Re: Optimizing out unreferenced variables Message-ID: <1991May11.070649.413@vlsisj.uucp> Date: 11 May 91 07:06:49 GMT References: <1475@ecicrl.ocunix.on.ca> <13206:May719:03:1491@kramden.acf.nyu.edu> <1477@ecicrl.ocunix.on.ca> <8874:May914:42:5791@kramden.acf.nyu.edu> Sender: usenet@vlsisj.uucp (Usenet News) Reply-To: davidc@vlsisj.uucp (David Chapman) Organization: Compass Design Automation San Jose, California Lines: 89 In article <8874:May914:42:5791@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: |> In article <1477@ecicrl.ocunix.on.ca> clewis@ferret.ocunix.on.ca (Chris Lewis) writes: |> > >It's a whole bunch more portable and useful to give the user some |> > >options to print out those strings. End of story. |> > What exactly do you mean by this? what(1)? |> |> No. what(1) is not supported by the language or the complete programming |> environment, so it is inherently unreliable. |> |> > A -V option? |> |> All that's important for this problem is that each library provide a |> routine that returns a version string. Try this: write in C++ and define a class whose constructors link themselves into one list. It should have a member function that can traverse the list printing the version string which is the argument to the constructor. You put one of these version objects into each source file (outside any functions) with its version number. Then your "version" function simply invokes this printing function on its own version variable, and voila! - all your version strings get dumped to the screen or a convenient file. You don't need to know the variable names, and the system extends itself every time you add another file. Here's an example that I just whipped up. I haven't tried to compile or run it yet, so use it at your own risk. :-) It's free for the taking. /************************** declaration file *************************/ class fileversion { public: fileversion(const char *ver); void printversions(void); /* extend as you see fit */ private: char *_ver; static fileversion *firstver; fileversion *nextver; }; /************************* implementation file ***********************/ /* list terminator */ fileversion *fileversion::firstver = 0; fileversion::fileversion(const char *ver) { _ver = ver; /* save file version */ nextver = firstver; /* link ourselves in */ firstver = this; } void fileversion::printversions(void) { fileversion *cur; /* could be fancier, obviously */ for (cur = firstver; cur != 0; cur = cur->nextver) printf("%s\n",cur->_ver); /* works since this is a member function */ } /*************************** sample usage ***************************/ /* "static" in declaration optional and irrelevant */ static fileversion anyvariablename("file foo.cpp 3.1.2 10-May-91"); void printallversions(void) { anyvariablename.printversions(); } /*************************** end of example ************************/ The list is self-constructing; all of the constructors are called via the linker so you don't need to do it yourself! This is also why you don't need to know the names of the variables. And the optimizer is guaranteed not to optimize it away! It's probably not a good idea to inline the constructor. I found this out the hard way. Zortech C++ constructors seem to be a minumum of 200 bytes, and on a DOS machine memory is tight. :-( Thanks for the idea, Dan! David Chapman {known world}!decwrl!vlsisj!davidc vlsisj!davidc@decwrl.dec.com