Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Changed to JG, fixed links and the exception

...

Constants should be declared as static and final. For example:

Code Block

private static final int SIZE = 25;

Although final can be used to specify immutable constants, there is a caveat when dealing with composite objects. SeeVOID OBJ02OBJ50-J. Never conflate confuse immutability of a reference with that of the referenced object for more details.

Noncompliant Code Example

This noncompliant code example calculates approximate dimensions of a sphere, given its radius.

...

The methods use the seemingly random literals 12.56, 4.19, and 6.28 to represent various scaling factors used to calculate these dimensions. A developer or maintainer reading this code would have little idea about how they were generated or what they mean and consequently would be unable to understand the function of this code.

Noncompliant Code Example

This noncompliant code example attempts to avoid the problem by explicitly calculating the required constants.

Code Block
bgColor#ffcccc

double area(double radius) {
  return 4.0 * 3.14 * radius * radius;
}

double volume(double radius) {
  return 4.0 / 3.0 * 3.14 * radius * radius * radius;
}

double greatCircleCircumference(double radius) {
  return 2 * 3.14 * radius;
}

The code uses the literal 3.14 to represent the value ?. Although it removes some of the ambiguity from the literals, it complicates code maintenance. If the programmer were to decide that a more precise value of ? is desired, all occurrences of 3.14 in the code would have to be found and replaced.

Compliant Solution (Constants)

In this compliant solution, a constant PI is declared and initialized to 3.14. Thereafter, it is referenced in the code whenever the value of ? is needed.

Code Block
bgColor#ccccff

private static final double PI = 3.14;

double area(double radius) {
  return 4.0 * PI * radius * radius;
}

double volume(double radius) {
  return 4.0/3.0 * PI * radius * radius * radius;
}

double greatCircleCircumference(double radius) {
  return 2 * PI * radius;
}

This technique reduces clutter and promotes maintainability. If a more precise approximation of the value of ? is required, the programmer can simply redefine the constant.

Compliant Solution (Predefined Constants)

The class java.lang.Math defines a large group of numeric constants, including PI and the exponential constant E. Use predefined constants when they are available.

Code Block
bgColor#ccccff

double area(double radius) {
  return 4.0 * Math.PI * radius * radius;
}

double volume(double radius) {
  return 4.0/3.0 * Math.PI * radius * radius * radius;
}

double greatCircleCircumference(double radius) {
  return 2 * Math.PI * radius;
}

Noncompliant Code Example

This noncompliant code example defines a constant BUFSIZE, but then defeats the purpose of defining BUFSIZE as a constant by assuming a specific value for BUFSIZE in the following expression:

Code Block
bgColor#FFcccc

private final int BUFSIZE = 512;

// ...

public void exampleFunction() {
  int nblocks = 1 + ((nbytes - 1) >> 9);  // BUFSIZE = 512 = 2^9
  // ...
}

The programmer has assumed that BUFSIZE is 512, and right-shifting 9 bits is the same (for positive numbers) as dividing by 512. However, if BUFSIZE changes to 1024 in the future, modifications will be difficult and error prone.

Compliant Solution

This compliant solution uses the identifier assigned to the constant value in the expression.

Code Block
bgColor#ccccff


private final int BUFSIZE = 512;

// ...

public void exampleFunction(int nbytes) {
  int nblocks = 1 + (nbytes - 1) / BUFSIZE;
  // ...
}

Exceptions

DCL02DCL56-EX1: The use of symbolic constants should be restricted to cases in which they improve the readability and maintainability of the code. When the intent of the literal is obvious, or where the literal is not likely to change, using symbolic constants can impair code readability. The following noncompliant code example obscures the meaning of the code by using too many symbolic constants.

Code Block
bgColor#ffcccc

private static final double AREA_FACTORFOUR = 4.0 * Math.PI;
private static final double VOLUME_FACTORTHREE = 4.0 / 3.0 * Math.PI;
private static final double CIRCUMFERENCE_FACTOR = 2.0 * Math.PI;

double areavolume(double radius) {
  return AREA_FACTORFOUR */ radiusTHREE * radius;
}

double volume(double radius) {
  return VOLUME_FACTOR * radius Math.PI * radius * radius;
}

double greatCircleCircumference(double radius) {
  return CIRCUMFERENCE_FACTOR * radius;
}

The values 4.0 and 3.0 in the volume calculation are clearly scaling factors used to calculate the sphere's volume and are not subject to change (unlike the approximate value for ? π), so they can be represented exactly. There is no reason to change them to increase precision because replacing them with symbolic constants actually impairs the readability of the code.

Risk Assessment

Using numeric literals makes code more difficult to read, understand, and edit.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

DCL02DCL56-J JG

low

unlikely

high

P1

L3

Related Guidelines

C ++ Secure Coding Standard: DCL06-CPPC. Use meaningful symbolic constants to represent literal values in program logic

C++ Secure Coding Standard: DCL06-CCPP. Use meaningful symbolic constants to represent literal values in program logic

Bibliography

 

DCL54-JG. Do not declare more than one variable per declaration      01. Declarations and Initialization (DCL)      DCL55-J. Properly encode relationships in constant definitionsImage Added