9 ms·
Global variables are bad (2013)
- LeoPanthera 8y agoI use global variables, though usually as constants, to hold the command line arguments to my programs. I don’t know if this is “good” or not but it seems to work OK.
- droidist2 8y agoIt's fine as long as the variables aren't mutable. Shared mutable state is the real killer.
- dev_dull 8y agoI still have a hard time being dogmatic about this. For some simple multithreaded apps I'll use a global "STOP" variable, which I mutate when shutting down. All of the functions check this before attempting to gracefully exit. I've done alternatives and I've never really seen the benefit.
- kyberias 8y agoThe threads could take a pointer/reference to the "stop variable" and use the reference instead of accessing the global variable directly. That allows you to mitigate many problems of global variables. Sorry, if you already do this.
- dev_dull 8y agoHonest question but what do I really gain in this scenario? Now all worker function arguments are N+1. I feel like it’s the waterbed affect and the complexity is simply pushed around elsewhere. It seems like there’s simply a reasonable cognative “maximum” of global before it becomes unworkable. My gut tells me it’s between 1 and 4.
- setr 8y agoI think the main benefit is that every function relying on the stop variable is clearly defined as such, as opposed to having to find out manually who is reliant on it based on usage; its not so much moving complexit around as it is making things more explicit. im not sure how useful this is in practice though, for the common case
- Someone 8y agoGain? You could pass different pointers to each worker function, giving you a way to partially shutdown your process, or to shutdown some workers first, and workers they depend on later. Of course, if you don’t need that, it’s not a gain, and a global is fine. Globals also are fine if you are resource constrained (e.g. if you have a few kilobytes of RAM or even less) Getting your code running in it may trump everything else.
- kyberias 8y agoFor one thing, you immediately make that function unit-testable.
- red75prime 8y agoThen you want to make a library out of it and are stuck with a single stop-domain.
- sgillen 8y agoThat honestly seems like a pretty good use case for global variables in a single entry point program.
- partycoder 8y agoThen those would be global constants not global variables.
- nradov 8y agoConceptually yes, but some languages don't have distinct constructs for constants and just use variables (sometimes even mutable) for everything.
- kyberias 8y agoIn many programming languages, "constants" are compile-time and therefore cannot be used for holding command-line parameter value.
- partycoder 8y agoThe only invariant of a constant is that it remains constant. The way that abstraction is represented is implementation specific. Compiler generated constants can still change, because registers and memory are mutable.
- oweiler 8y agoNot bad but I always try to limit the scope of variables as much as possible. Makes reading the code easier.
- nine_k 8y agoA variable us something that varies, mutates, changes value, call it what you will. Global mutable state (i'd say, any non-local mutable state) complicates things and is a defect attractor. Global constants are fine. Something like pi is as global as it gets, and it's never a problem. There's an intermediate case of "global config info" which is technically mutable but is only mutated during a program startup, and stays constant during execution.
- AstralStorm 8y agoThat is presuming they stay constant forever. Which generally only makes sense for mathematical constants and type bounds. Otherwise it is better to pass them in (via dependency injection or otherwise) encapsulated so that enhancing the code for them to become variable or have versions is easy.
- mpartel 8y agoThe only (relatively minor) downsides I can see are: (A) it makes the code "singleton" by default: you can't instantiate two objects of the same class with two different values for the global argument (B) unless the global argument is declared in the same class, it slightly obfuscates the fact that a class depends on the argument (compared to all dependencies being constructor parameters) (C) it makes testing, especially multithreaded testing, more awkward and error-prone: tests have to set and reset global variables It's easy enough to refactor (A) where needed, as long as you have control of the code, and (C) can be worked around with good enough test helpers. I think one can reasonably argue both for and against the convenience outweighing these downsides.
- V-2 8y agoPerhaps they are minor if there's one or two global variables. Once they're used liberally and there's plenty of them, the resulting bugs can become so elusive it can drive you mad. A bug can be extremely hard to replicate, because it only arises from a very specific sequence of events that step-by-step flip the globals into an overall invalid state. And it's virtually impossible to determine "whodunnit". It's a perfect recipe for "the app sometimes crashes on Thursdays" scenario.
- mpartel 8y agoAh, I meant to reply specifically to the command line flags use case. For most other uses of globals, I fully agree.
- V-2 8y agoAh, then I misunderstood you, sorry. Of course this is a bit of a red herring anyway... As the original commenter remarked already, command line flags may be stored globally (eg. as read-only fields), but won't - and shouldn't - be variables. They're only given once, and their values aren't going to change throughout the program's running time. So they're essentially constants, which is fine.
- kulu2002 8y agoI remember, in one of my earlier projects, we had code quality metric which used to run after each fortnightly build and integration. This tool used to count no. of global variables added to C and public variables added in C++ source code. Even if single such variable is reported, author of that code had to justify use of global/ public variables. P.S. That doesn't mean there were no public/ global vars in legacy code. This practice started when code quality and system stability gradually started declining by their overuse
- __sr__ 8y agoAre they really? I agree that global variables are horrible in a language like C where they are truly “global” because of the lack of namespaces. But in a language like Python, they are tolerable because they are not truly global — they are restricted to the particular module. I am not saying they are great, but they are not as horrible as they are in, say, C. Of course, care must be taken to ensure that they are abused, but that is true of any programming construct. If module global variables are considered truly horrible, the same can be said about instance variables inside classes. They are as good (or bad) as module globals in the sense that they represent shared state and can potentially be mutated by any method/member function in the class. Of course the functional programmers among us will say that shared state of any kind is bad, and I agree. But we are not talking about that here, are we?
- LolNoGenerics 8y agoI don't think anyone argues variables with module scope. Because as you say they are not global.
- __sr__ 8y agoWell, there have been cases where I was asked to get rid of them by people reviewing my code — for no reason other than that global variables are “considered harmful”.
- cakoose 8y agoMutable variable that have exactly one instance (globally) cause some of the same issues, which is why people might casually lump them in with "global variables". (It would be nice if everyone used more precise terminology, though.)
- nine_k 8y agoSome modules are unlike others. Try setting `sys.stdout` in one extremely local function, observe ripples everywhere. It's not common, fortunately; hacking `sys.path` is more common, and is sometimes done at import time. With all its upsides, Python has a problematic global state story; it's easy to shoot yourself in the foot.
- bluetomcat 8y agoI'll play the devil's advocate. Global (shared) variables are fine when they represent non-instantiable program state and have descriptive names, with a clear semantic contract for mutating their state. Essentially, something like `the_world.rotation_speed` is a good example.
- mpartel 8y agoWhat if you, one day, want multiple worlds for some reason? I'm developing a game in Unity, and the programming culture around it encourages globals and singletons to an unhealthy degree. I pushed back against them heavily in our project. As a result, it was very easy to add a previously unplanned split-screen mode one day, thanks to the codebase (e.g. the UI and input modules) not assuming that there's only ever one local player.
- bluetomcat 8y agoIn the basic case when you don't need to clone the world, you avoid the passing down on the call stack of what is truly a global variable, disguised as a local instance. As a casual reader of such code, you might be deluded that `the_world` in `func1` is something different from `the_world` in `func2`, when they are the same. If you plan to "virtualise" stuff later, instantiation is certainly the way.
- mpartel 8y agoI'd rather readers of such code take the (IMO minor) extra effort to consider the possibility of the worlds being different rather than bake the assumption that they're the same into even more code. That's how globals spread around your codebase, little by little, until it's very hard to refactor away from them. Better to just say no from the start. Also, if you have so many globals that passing them around as parameters / instance variables becomes truly tedious, that can be a valuable signal that the program is poorly structured. Of course, none of this matters in small codebases, as long as they stay small.
- JimDabell 8y ago
- jameslk 8y agoI guess this is pretty basic, but it creates tight coupling between unrelated code, as described here: https://en.wikipedia.org/wiki/Coupling_(computer_programming)#Types_of_coupling https://en.wikipedia.org/wiki/Coupling_(computer_programming...
- drblast 8y agoIt's funny how much I dislike the top two alternatives to globals, at least how they're typically implemented today. For me it's a case where the cure is worse than the disease. I've worked with a codebase where the global state was passed around as a configuration object, and that made heavy liberal use of dependency inversion. No other code base I've seen was so obtuse...it was nearly impossible to know what a line of code did but looking at it. Dependency injection and configuration objects certainly can be useful, but the bad design they seem to encourage makes me think very carefully about using them.
- AstralStorm 8y agoIt is still global state, albeit better boxed and automatically attached to places that need it. If it is mutable, you have even more problems. About the only way to deal with this is to strictly enforce contracts and completeness when using and implementing such a thing.
- HumanDrivenDev 8y agoWhat is with all this contrarianism against basic software best practices in tech circles these days? First the thread about how great copy pasting was, and now people praising the use of global variables. What's next - goto advocacy? Segmentation faults as the preferred error handling technique?
- jimjimjim 8y agogotos are fine. people are tired of guidance being turned into rules and then into dogma.
- notacoward 8y agoI wouldn't say gotos are fine, but they're sometimes better than alternatives. I'll take a "goto" to an error-cleanup cascade at the end of a function over ten nested three-line functions, a mini state machine, or lots of little state variables (the most common alternatives) any day. If the language has destructors or deferreds or anything else that automatically triggers when leaving scope that's probably even better, but some older languages - notably C - don't, so dogma often leads to worse alternatives.
- emerged 8y agoI've wondered about the parallels between globals in code and open door immigration policies, etc. The left/right political axis may conceptually span across more than just politics and the current tech climate is more left.
- notacoward 8y agoBoth global variables and gotos are bad. On the other hand, the contortions some people go through to get the same effect without using the actual construct are often worse. That's the real point. Design and implementation decisions should be judged based on what they do, not their superficial appearance. If code is littered with singletons and often-thrown exceptions, it's worse than if the programmer had been honest about using globals and gotos.
- a1369209993 8y ago
- dingo_bat 8y ago> Really Bad Reasons to Use Global Variables > "I don't want to pass it around all the time." This is not a bad reason at all. I think this is the best and most used reason. And no alternative is provided in TFA.
- oweiler 8y agoI disagree. Passing around variables, while unpleasant, at least makes dependencies explicit.
- FrozenVoid 8y agoGlobal variables are fastest, least memory intensive way to transfer state. If you need thread safety, atomic variables are still faster and more efficient than any alternative. You can create pseudo-namespaces in C like Global_ and avoid name clashes too.