Global Constants Considered Harmful

In modern languages like JavaLanguage it is impossible to write global constants.

Perhaps for very small values of "impossible". I create global constants in Java on a regular basis:

    package com.package;

public class Thing { public static final GLOBAL_CONSTANT=23; }
com.package.Thing.GLOBAL_CONSTANT is both constant and globally accessible.

Either way, it is always possible to revive the monster and create classes with public instance variables that serve the purpose of GlobalConstants?.

GlobalConstantsConsideredHarmful because of CollateralEffects.

You mean like the extreme harm caused by defining PI = 3.14159265358979323846264338... globally?

Neither of these two pages really explains itself.

I use global constants all the time in Java, as public static final class members. And I don't see why you'd write a maintainable decent-sized program without them. What's the harm?

Agreed. Often, a global constant is the right thing for the job. When you have a constant value (or more generally, an immutable object) that applies to the entire program, you want to give it global scope. Otherwise, in each locality that uses the value (or object), you have to redefine it (or reinstantiate it). PI is an obvious example, but any constant that applies globally ought to have either global scope or a global accessor function. In this case, a global constant is how you implement OnceAndOnlyOnce.

This is not the same as having a GlobalVariable (mutable object), because writes to a GlobalVariable change the program's state. Unless state changes are localized, it becomes hard to guard against CollateralEffects and InvalidStateTransition?s. The end result is poor cohesion, poor coupling, and generally unmaintainable code (poor MaintainAbility). This argument does not apply, however, to global constants.


OK, I'll take a stab at the "PI = ..." example.

Consider a C++ implementation of this:

  #define PI 3.14159;
  const double PI = 3.14159;
  const float PI = 3.14159;
  const math::rational PI(22,7);
  const math::algebra PI(lambda(...));
The question now becomes, which value of the constant should I use? Unless you can unambiguously define that only one of these could ever, under any circumstances (within the scope of your code) be correct, then you have a problem, with the concept of a global constant.

Should it be a compile-time constant, or a run-time one (the obvious disadvantage of having a global math.h that defines these constants is that it would be a very "stable" class - heavily depended upon, potentially causing a "recompile the world" event if you add a constant (or change something).

In my experience, global constants, even obvious things like PI, rarely need to be global. How may of your files actually do math that really requires access to the constant? Even if you have a complex scientific/engineerring package, most of your standard formula can be coded as packages that buffer your end application from the details of the math (trivial example: If you need the area of a circle, then you use a "circle" class with an "area" method).

Of course, you can probably find an example where you really do want to use the constant everywhere, but I'd consider that to be a very strong smell. Think hard before you write code that uses the same identifier over, and over, again.

-- DaveWhipp

That's not really a counterargument per se, although those are good points, because (1) the type of the constant wasn't the topic, it was its global const-ness. You can have one global const per type (22/7, 3.14, (3.14 + i*0), etc). (2) when it is used only in those modules/packages/classes/methods that it is needed, it nonetheless is, and should be, global anyway, because of OnceAndOnlyOnce...

The reason that M_PI became a global constant in a C standard include file wasn't just for convenience, it was also to keep people from defining it over and over and over again... sometimes inconsistently (incorrectly). In the bad old days, I saw, with my own two eyes, quite a few functions that defined PI, and gave it incorrect values. And even more where it was defined correctly, but multiple times in the same program, and worse, each one having a different number of significant places.

One of the most important definitions of pi actually isn't in decimal, it's the hexadecimal value that gives the best approximation on whatever the current cpu is... this sort of thing can be critically important when numerical analysis is of importance, and you absolutely don't want anyone but an expert to be the one to define it, and then it should be available in exactly one place.

There really isn't any alternative, when you think about it. Try to have pi as a local constant, not global. But given OnceAndOnlyOnce (for the above important functional reasons, not just stylistic reasons), how are the different places that want to have a local constant for PI going to initialize its value? From a global definition.

That's a fascinating paragraph above about the hex versus decimal approximation of pi, considering the multiplication of numerical error in iterative solutions when solving, say, differential equations. Perhaps some of the pi discussion could go on a ScientificComputing? page, which we don't seem to have. -- ElizabethWiethoff


I see nothing on this page that describes how global constants can cause "CollateralEffects". Can anyone defend this page? -- EricHodges


See also ValueOfPi


EditText of this page (last edited January 11, 2005) or FindPage with title or text search