bill@twwells.uucp (T. William Wells) (04/18/89)
My own solution to the problem of globals is this: State variables, ones which map fairly obviously into the current processing state of a program subsystem, should be globals. Note this is "should", not "may". Variables which are dependent on local context should be function parameters. Variables which are intermediate may be either globals or function parameters, with clarity and efficiency (and sometimes the quirks of C) determining which. When a given subsystem is small (e.g., a function or two), parameters should generally be used, though there are times when globals are more appropriate. As an example: I tend to have to write complex systems which operate with control structures that contains lots of data. It would be costly to pass the address of the control structure (about 10% in space and execution time, I often write small functions) to all the routines in the system and wouldn't add one bit to program clarity; what I do is have the system interface routines store the address of the structure as a global and have each routine which needs it use it. In this case, an obvious part of the operating state is the current context the system is operating in, thus that current context should be a global. Another example of a state variable is the program parameter, typically set at the start of the program and never changed thereafter, or only changed on user request. Again, this often maps directly and obviously into the current program state and thus should be global. --- Bill { uunet | novavax } !twwells!bill (BTW, I'm may be looking for a new job sometime in the next few months. If you know of a good one where I can be based in South Florida do send me e-mail.)
ark@alice.UUCP (Andrew Koenig) (04/18/89)
In article <826@twwells.uucp>, bill@twwells.uucp (T. William Wells) writes: > My own solution to the problem of globals is this: > State variables, ones which map fairly obviously into the current > processing state of a program subsystem, should be globals. Suppose you have some kind of transaction processing system with a menu-oriented user interface. The state of the screen is presumably one of these `state variables' you mention. Now someone comes along and tells you to rework your system to allow split screens -- that is, multiple transactions on one physical screen. Presto! You have just been forced to rework your design to distinguish between logical and physical screens and to know which logical screen you're working on, and how the state of the logical screen relates to the state of other things in your program you must now replicate, and so on. Thus even in `obvious' cases like this, it may sometimes pay off to put things that look at first as if they should be global into a structure of some kind whose address is passed around to every function that needs those entities. Of course, this is a pain; hence many people don't do it. It would be nice if C had some kind of facility for passing stuff of this kind around implicitly so you didn't have to write an extra argument for every function and every reference to `global' data. Now you know one of the reasons C++ works the way it does. -- --Andrew Koenig ark@europa.att.com
bill@twwells.uucp (T. William Wells) (04/19/89)
In article <9215@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes: : In article <826@twwells.uucp>, bill@twwells.uucp (T. William Wells) writes: : : > My own solution to the problem of globals is this: : : > State variables, ones which map fairly obviously into the current : > processing state of a program subsystem, should be globals. : : Suppose you have some kind of transaction processing system with : a menu-oriented user interface. The state of the screen is presumably : one of these `state variables' you mention. Yes. Sort of. It depends on how you think of the program. : Now someone comes along and tells you to rework your system to : allow split screens -- that is, multiple transactions on one : physical screen. Presto! You have just been forced to rework : your design to distinguish between logical and physical screens : and to know which logical screen you're working on, and how the : state of the logical screen relates to the state of other things : in your program you must now replicate, and so on. You've criticised the wrong thing. If the program was designed to handle only one screen, it is irrelevant whether you passed the variables as parameters or stored them as globals: it's going to be a bitch to rework your program to make it deal with multiple windows. (Ask me, I know! :-) But, if you had considered the possibility that the program would have to deal with multiple windows, you'd have grouped the window parameters in one place and kept them separate from the screen parameters. Then, all you'd have to do is put the window parameters into a structure, make a pointer to the current window one of the globals, modify the references to the erstwhile globals, and modify the necessary code to correlate the screen parameters and the window parameters, e.g., the window switching code and cursor positioning code. : Thus even in `obvious' cases like this, it may sometimes pay off : to put things that look at first as if they should be global : into a structure of some kind whose address is passed around : to every function that needs those entities. Well, I'd agree that it might be a good idea to put all the stuff into a structure; that can make life easier, not to mention encouraging encapsulation of the data. But it still doesn't deal with the question of whether the structure (or pointer) should be a global or a parameter. --- Bill { uunet | novavax } !twwells!bill (BTW, I'm may be looking for a new job sometime in the next few months. If you know of a good one where I can be based in South Florida do send me e-mail.)