Naming: Why should named constants be all uppercase in C++/Java?

Viewed 43951

I know, that for C++ and Java it is a well established naming convention, that constants should be written all uppercase, with underscores to separate words. Like this (Java-example):

public final static Color BACKGROUND_COLOR = Color.WHITE;
public final static Color TEXT_COLOR = Color.BLACK;

This naming convention is easy to understand and to follow, but I ask myself, why choose this naming convention over the normal naming-convention for variables:

public final static Color backgroundColor = COLOR.WHITE;
public final static Color textColor = COLOR.BLACK;

Theres seems to be no need to change the look of constants. If we want to assign a value to them, the compiler will prevent this anyways. Actually it makes problems, if later the constant will be changed into a proper variable (because the colors get configurable for instance).

So what's the ultimate reason to write named constants all uppercase? Historical reasons?

15 Answers

I think it is not a technical problem but rather a psychological one. Naming conventions are not for the compiler to process (the computer does not really mind names) but rather for the programmer that is browsing the code to have as much information as possible with as little effort as required.

Using a different naming convention is clearly telling the reader that what you are reading is something that is FIXED at compile time and you don't need to follow through code to determine where and how the value got there.

I believe in C++ it's a convention carried over from the days of using the preprocessor to #define constant values. Back then, it was done to avoid having the preprocessor trample all over your source code, as the usual conventions for C function and variable names would make them mixed case or lower case.

From a C++ point of view, I would say that it's a bad idea to make your constants all-uppercase. I've had to debug more than one build problem because of this - remember that the C++ preprocessor does know nothing about namespaces and naming scope and will happily substitute what it thinks is appropriate even though it is rather inappropriate.

I can imagine that initially, back in the C days, people would implement "constants" symbolically, using the pre-processor:

typedef unsigned int Color;
#define BACKGROUND_COLOR 0xffffff

Such "constants" are just prettified literals, and as such they don't behave quite as variables. You can't, for example, take the adress of such a "constant":

Color *p = &BACKGROUND_COLOR; // Breaks!

For this reason, it makes sense to have them "stand out", as they're really not just "variables you can't change".

If I know something is a constant, I can refer to it multiple times and know it won't change. In other words, I know that:

Color black = Colors.BLACK;
foo(black);
foo(black);

is the same as:

foo(Colors.BLACK);
foo(Colors.BLACK);

That can be useful to know sometimes. Personally I prefer the .NET naming convention, which is to use Pascal case for constants (and methods):

Foo(Colors.Black);
Foo(Colors.Black);

I'm not a big fan of shouty case... but I do like constants being obviously constants.

Do not use ALL_CAPS for constants just because constants used to be macros.

This quote from C++ Core Guidelines sums it all.

In C (and then C++), symbols that were defined with the preprocessor #define directive were written all in caps as a loud signal to developers that the code was not as it seemed and to not treat as a normal symbol. Constants did not initially exist in K&R C (although const was brought back from C++ later) so developers used #define instead, hence the caps.

For some reason, this got twisted into Java as "constants are caps", hence the current misguided (IMO) convention.

I think uppercase constants are a bad heritage from C. The logic behind is the same as when using underscores as prefixes for private members. This is technical stuff which is already expressed by Java keywords like private or, in the case of constants, static final.

With uppercase constants long formulas are much easier to read, you don't have to guess which element can vary and which can not. It's of course only a convention, but helpful one.

It's a workaround for your development tools not being able to spot the properties of an identifier in a convenient way.

Much like Hungarian notation.

When your IDE gets better, you won't need any naming convention but the one that dictates that a name is comprehensive information on what an identifier means.

Even that may evolve: why not create a programming system where you just create identifiers, and add properties to it like "brief description", "type", ... When the tool arrives that can do this in a convenient way, I'm in. "Intentional Programming" is a hint.

Probably you are right. Computers and compilers (especially) were not so fast as today.

Joel Spolsky mentioned in one of his essays how impressed he was with compilation time of new version of Turbo Pascal.

I remember when compilation of not too big program (10-20KLOC) with overlays in Turbo Pascal 5.0 on PC XT 10MHz took about 20 minutes...

I suppose that waiting for compilation to detect error was not acceptable.

And convention like that helps to avoid errors and wasted time during broken compilation.

When programming, it is important to create code that is understandable by humans. Having naming conventions helps to do this. This is best when looking at code that you didn't write and makes the code more maintainable because it is easy to distinguish from constants and variables.

Coding conversions are to improve readability. You don't have to use letters. Java allows $ symbol for example.

public final static Color $$ = COLOR.WHITE;
public final static Color $_ = COLOR.BLACK;

You could number your variables too, but that doesn't mean its a good idea. ;)

This is purely to help the programmer understand what he or she is looking at from a glance. It helps to know that a constant is being used so that the value won't change no matter how you refer to it.

There isn't really a reason regarding the compiler side of things. Naming conventions are purely that, conventions, not really technical restrictions.

Related