Programming style, avoiding globals.

Blitz3D Forums/Blitz3D Programming/Programming style, avoiding globals.

Craig H. Nisbet(Posted 2005) [#1]
Hey guys, I've been talking to some of the pro coding guys at work here, and they tell me that global variables are generally a no-no. I don't really understand why. How are global veriables avoided? Is this more a C/C++ thing?


WolRon(Posted 2005) [#2]
No, it's a game/app thing.

In apps, you generally try to avoid globals because of memory issues.

In games, you generally use lots of globals because of speed issues.


But you still don't want to overdue it. Only create as many as necessary.


fall_x(Posted 2005) [#3]
If you have a lot of global variables, it's not very clear wich variables are used where. So when possible, they use local variables and parameters, and possibly types.
It's just better, especially when you're not the only one who's going to work with the code.


Strider Centaur(Posted 2005) [#4]
Globals should be avoided in games just as much as in apps. However, Blitz dosn't really give us any way to avoid them. We can not pass pointers, so globals are what we use. Really on of the best ways to avoid globals is to use a OOP language.

I Guess in a way you can cut down on globals with Types and Arrays, but arrays are basicly globals and Types are over kill for something like State variables and what not.

I think if you are concerend with most of that fall_x pointed out, you could adopt a nameing convention that helped make it clearer that a variable is a global. Also you can keep this in a common.bb file for easy referance while coding. Comments are you friend so use them. :)

I have seen some people use: g_variableName

Thats a fairly clear way to mark something as global. :)


SurreaL(Posted 2005) [#5]
Hrm.. I thought that globals were allocated in RAM, whereas locals were allocated on the stack.. wouldn't this make locals considerably faster to use? I'm not sure why you would ever want to use lots of globals, really. (Although I could be wrong)

As far as avoiding globals.. well.. not really sure how that can be done without having somewhere else to store the information. (As Strider suggests.. types aren't necessarily required for every little piece of data you need to store.) I *have* heard of people placing literally everything in a type though, so I guess ultimately it's up to what you prefer.


jfk EO-11110(Posted 2005) [#6]
Isn't the stack located in the RAM as well? Or is there some special Stack Cache in the CPU or something? I guess not.


Techlord(Posted 2005) [#7]
I'm guilty of literally placing everything in a type. Types provides a small amount of encapsulation. I also avoid globals by passing the values from function to function directly. However, it makes for really huge Function Argument List.


Strider Centaur(Posted 2005) [#8]
Surreal, thats true in many Languages, but I don't beleive in B3D its the case, I think in B3D its all ram.

JFK, I think he means in the part of ram handled by the stack pointer of the CPU.


WolRon(Posted 2005) [#9]
If I'm not mistaken, all variables passed to functions, and local variables to that function are pushed onto the stack, and later popped off of the stack, requiring a small amount of overhead.
If the function was called a significant amount of times, and had lots of passed parameters or created locals, it might make a performance loss.
Although with computers being as fast as they are today, except in extreme circumstances, it will most always be negligible.


Barliesque(Posted 2005) [#10]
I'm getting more and more into using types for global needs.

@Frank Taylor:
Not that I know what your code looks like, but if you're using types effectively, you ought to be able to *save* the number of parameters you're passing. By passing a reference to the type entry (rather than a specific field) all of the individual fields can be referenced by the function, using that one parameter. When passing a user-defined type like this, you're only passing a pointer to the data container, so the overhead is minimal.

I personally prefer to avoid lots of globals for organisational reasons. Types give me a sophisticated method of organising the information so that it's accessible in an intuitive way---which I need if I'm going to pass my code to somebody else, or as is more often the case, come back to code I wrote ages ago (which is practically the same thing!)

Also, if you want to make use of other people's code, you may find that you've got global variable names in common. Types tend to give your code a lot more portability than globals--although name clashes can still happen, of course.

And one more advantage of Types over globals: If you're using Protean, or another editor that offers code completion, you get a handy-dandy popup list of the fields as you type. FAR FAR handier than lengthy globals with multi-part naming conventions!


Picklesworth(Posted 2005) [#11]
Best use types than globals, in my experiance. They're more fun to access too, especially when you can get something like app\menu[5]\r=255 :D


Techlord(Posted 2005) [#12]
that I know what your code looks like, but if you're using types effectively, you ought to be able to *save* the number of parameters you're passing. By passing a reference to the type entry (rather than a specific field) all of the individual fields can be referenced by the function, using that one parameter. When passing a user-defined type like this, you're only passing a pointer to the data container, so the overhead is minimal.


Agreed. The technique is only employed with variables shared by many types that are not fields of a specific type.

I have found that adopting a Verbose Label Convention can prevent code conflicts and improves portability. Even with using Globals! The convention can be as simple as using a label prefix for all types, variables, arrays, functions, etc within your library.
MyLib_{Label}
Here's a example of a Label Convention that I've adopted
Syntax: 
[Object][Purpose] (ie: ClockSet) 
[Object][Property][Purpose] (ie: ActionIntSet(myaction,index,255)) 
[Object][SubObject][Purpose] (ie: DatabaseRowNext(db)) 
[Object][SubObject][Property][Purpose](ie: CameraRumbleXSet(camera,2.0)) 
Just adding a prefix can allow the code to port anywhere. If you don't adopt a Labeling technique of some sort, it gets very difficult to code large programs because you start running out of labels.


Barliesque(Posted 2005) [#13]
I think that's an excellent coding practice. I try not to get too verbose, but the great thing is only your type definition names are what have to be verbose. The fields inside can be as simple as you like--though clarity is always a good thing.

You know, now I'm inspired to just drop the use of globals completely. ...Yes, of course. Down with globals!


Qube(Posted 2005) [#14]
Those so-called 'pro-coders' need their heads looking at regarding global variables!

Globals are very important in most programmes.

Take a simple example for games - a players position, weapons available, health, etc would be global

Take a simple application - notepad. alot of that would be requiring access to global variables. Position in the text file, save state, is something copied into memory etc etc.

In the end does it really matter how a program is constructed?. So long as its stable and speedy enough for the purpose it was intented, who's got the right to dictate on your programming style?


WolRon(Posted 2005) [#15]
It's not about programming style, it's about speed and memory.

Globals require less speed but take up more memory.

It's not as big an issue as it once was, but in some circumstances, it might still be.


tonyg(Posted 2005) [#16]
Some OOP related languages use registers for locals which makes them VERY fast compared to globals. The other suggestion is each unit should be self contained so having 'global globals' makes them less portable.
(Think : I might have been reading too much OOP stuff for Bmx)


jfk EO-11110(Posted 2005) [#17]
the number of registers is pretty limited. And keep in mind that registers are used by the commands anyway. Using globals isn't bad at all, it's just one of those "Mr. God is now telling you how the REAL coders work" thing, and I think it sucks extremly.
If you are working in a team you may have to take care to use a clever prefix convention for the names of your globals, so there won't be conflicts with common variabe names like x,y,z or "player" etc.

You can also use this method for a modular library, using a describing and unique prefix eg: "netlib_x#".


HappyCat(Posted 2005) [#18]
I've being doing OOP stuff for years and I think the only time I've used a global variable in the last decade is in Blitz.

But it doesn't offend me at all. I use Types wherever it makes sense to collect global together, I use Protean so I can group my globals in a region at the top of each file and I use a naming scheme a bit like Frank Taylor's for stuff that isn't in Types - so it all feels reasonably OO anyway.

The only thing that really does offend me about Blitz is using . for types and \ for fields - aaargh! It's so damn confusing when I go back to VB.Net and start putting \'s in everywhere :-(


tonyg(Posted 2005) [#19]
For BlitzMax...
Locals get pushed onto the CPU registers, if available, while globals are always stored in system ram.


jfk EO-11110(Posted 2005) [#20]
That's surely very fast, and of course, whereever locals can be used, they should be used, especially when they are initialized in a function anyway. But when you need the value of it over multiple function calls or in multiple functions, it may be pretty slow to store and restore them, just to be able to use locals. But of course, the can be globals, arrays, types, or even bank entries.

Wouldn't that be a challenge for you, make a program with banks only (well, byside the neccessary handles, like bank handles). that would feel kind of like ASM coding.


Qube(Posted 2005) [#21]
It's not about programming style, it's about speed and memory.

Not what the topic title says :P