Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!sdd.hp.com!wuarchive!udel!ee.udel.edu From: new@ee.udel.edu (Darren New) Newsgroups: comp.lang.misc Subject: Re: Request For Comment About Handling Of Globals Message-ID: <38917@nigel.ee.udel.edu> Date: 12 Dec 90 20:04:27 GMT References: <1990Nov30.191454.29030@newcastle.ac.uk> <1990Dec7.195140.3022@arnor.uucp> <1189@ncis.tis.llnl.gov> Sender: usenet@ee.udel.edu Organization: University of Delaware Lines: 78 Nntp-Posting-Host: snow-white.ee.udel.edu In article <1189@ncis.tis.llnl.gov> turner@lance.tis.llnl.gov (Michael Turner) writes: >When is a global necessary? I think the answer is: almost never. >To me, the worst part of unconstrained use of global variables is the >uncertainty: when reading the code, you find yourself looking at something >that has no readily-available context or meaning; you don't know what is >going to change it and when. Actually, when you have no readily available context or meaning, a global can be most helpful when properly done. I was managing a few-person project in which globals were almost vital. One person was writing the "main" function and a few levels of nesting, another was writing the lowest levels of nesting, and others were writing various parts of the intermediate levels. It was done this way because the intermediate levels needed to be rewritten (to some extent) for each customer and software product, but the top-level menus would be the same for each type of software product and the bottom layers would be the same for all products. For example, the top level displayed the "print report" option on the main menu, the intermediate level calculated what was to go in the report and which columns went where, and the lowest level got the characters out to the printer. (There were actually four levels, but that's beyond the scope of my point.) Anyway, globals were needed because we could not afford to change the middle layers of every product when something needed to be passed from the top level to the bottom level. For example, if customer 17 needed two different printers supported, and customers 1 thru 16 only needed one, then getting programmers for 1 thru 16 to add the "which printer" parameter to their intermediate levels becomes a maintainance nightmare. My solution was to have all global variables actually be global; i.e., every programmer would know about them, and they would maintain only information that was truely global to all routines. To accomplish this, every global variable had to be in the "globals" header file of the appropriate layer (i.e., no "hidden" globals between only two modules). Also, and most importantly, each global had to have a comment describing what the variable "meant" independant of context. For example: BOOL file_is_open; /* client file is currently open */ BOOL file_is_ro; /* client file is open and readonly. false if not file_is_open */ Note that you don't *need* context to understand these globals (given, of course, that you understand our program model). Whenever you open the client file, you must set file_is_open to true and must set file_is_ro correctly also. Whenever you close the client file, you must set file_is_open to false and file_is_ro to false. Whenever a new global was proposed, the global and its comments were written up and distributed to all programmers. The comments were modified until all programmers thought them unambiguous. For example, the first comment for file_is_ro was /* client file is read only */ and one of the programmers said "What if it's closed?" In conclusion, global variables are just as useful and dangerous as global goto labels. Properly commented and maintained, global variables are helpful in reusability, not harmful. The biggest restriction is that global variables should be *GLOBAL* and not just shared invisibly between some subset of modules. I rarely notice people complaining about the global nature of some truely global variables like file handles, process IDs, file names, userIDs, and so on; I feel that this supports the idea that GLOBAL variables are safer than "invisible" parameters. Global gotos are helpful too, *IF* they are actually global, that is, if you can actually goto them at any time and have the desired effect. Witness, for example, interrupt vectors, the "main()" entry point, and software libraries. Each of these global goto-like mechanisms can be useful but only if calling "sin()" always gives you the expected documented answer. There are problems with "errno", but not because it is global, but rather because the data structure is too simple. -- Darren -- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware --- ----- Network Protocols, Graphics, Programming Languages, Formal Description Techniques (esp. Estelle), Coffee, Amigas ----- =+=+=+ Let GROPE be an N-tuple where ... +=+=+=