...
The meaning of the integer literal 18 is not clear in this example.
Code Block | ||||
---|---|---|---|---|
| ||||
/* ... */ if (age >= 18) { /* Take action */ } else { /* Take a different action */ } /* ... */ |
...
This compliant solution replaces the integer literal 18 with the symbolic constant ADULT_AGE
to clarify the meaning of the code.
Code Block | ||||
---|---|---|---|---|
| ||||
enum { ADULT_AGE=18 }; /* ... */ if (age >= ADULT_AGE) { /* Take action */ } else { /* Take a different action */ } /* ... */ |
...
Integer literals are frequently used when referring to array dimensions, as shown in this noncompliant code example.
Code Block | ||||
---|---|---|---|---|
| ||||
char buffer[256]; /* ... */ fgets(buffer, 256, stdin); |
...
In this compliant solution, the integer literal is replaced with an enumeration constant. (See recommendation DCL00-C. Const-qualify immutable objects.)
Code Block | ||||
---|---|---|---|---|
| ||||
enum { BUFFER_SIZE=256 }; char buffer[BUFFER_SIZE]; /* ... */ fgets(buffer, BUFFER_SIZE, stdin); |
...
Frequently, it is possible to obtain the desired readability by using a symbolic expression composed of existing symbols rather than by defining a new symbol. For example, a sizeof
expression can work just as well as an enumeration constant. (See recommendation EXP09-C. Use sizeof to determine the size of a type or variable.)
Code Block | ||||
---|---|---|---|---|
| ||||
char buffer[256]; /* ... */ fgets(buffer, sizeof(buffer), stdin); |
...
In this noncompliant code example, the string literal "localhost"
and integer constant 1234
are embedded directly in program logic and are consequently difficult to change.
Code Block | ||||
---|---|---|---|---|
| ||||
LDAP *ld = ldap_init("localhost", 1234); if (ld == NULL) { perror("ldap_init"); return(1); } |
...
In this compliant solution, the host name and port number are both defined as object-like macros, so that can be passed as compile-time arguments.
Code Block | ||||
---|---|---|---|---|
| ||||
#ifndef PORTNUMBER /* might be passed on compile line */ # define PORTNUMBER 1234 #endif #ifndef HOSTNAME /* might be passed on compile line */ # define HOSTNAME "localhost" #endif /* ... */ LDAP *ld = ldap_init(HOSTNAME, PORTNUMBER); if (ld == NULL) { perror("ldap_init"); return(1); } |
...
DCL06-EX1: While replacing numeric constants with a symbolic constant is often a good practice, it can be taken too far. Remember that the goal is to improve readability. Exceptions can be made for constants that are themselves the abstraction you want to represent, as in this compliant solution.
Code Block | ||||
---|---|---|---|---|
| ||||
x = (-b + sqrt(b*b - 4*a*c)) / (2*a); |
...