Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Generalized recommendation to include multi-statement macros.

Macros are frequently used to make source code more readable. Macro definitions consisting of a single statement do not need to be enclosed in a do()-while() (, regardless of whether they expand to a single or multiple statements (see PRE10-C. Wrap multiMulti-statement macros should be enclosed in a do-while loop) but should not conclude with a semicolon at the end of a macro definition. If required, the semicolon should be included following the macro expansion. Inadvertently inserting a semicolon at the end of the macro definition can unexpectedly change the control flow of the program, .

Another way to avoid this problem is to prefer inline or static functions over function-like macros. (See also PRE00-C. Prefer inline or static functions to function-like macros.)

In general, the programmer should ensure that there is no semicolon at the end of a macro definition that consists of a single statement. The responsibility for having a semicolon where needed during the use of such a macro should be delegated to the person invoking the macro.

Noncompliant Code Example

This noncompliant code example creates a macro definition for a for loop in the program. This macro takes an integer argument which is the number of times the loop should run. The programmer has provided a semicolon at the end of the macro definition by mistake.

...

Though the above example might not actually be used in code, it shows the effect a semicolon in a macro definition can have.

Compliant Solution

The compliant solution is to write the macro definition without the semicolon at the end, leaving the decision to have a semicolon or not up to the person who is using the macro.

Code Block
bgColor#CCCCFF
#define FOR_LOOP(n)  for(i=0; i<(n); i++)

int i;
FOR_LOOP(3)
{
  puts("Inside for loop\n");
}

Noncompliant Code Example

In this noncompliant code example, the programmer defines a macro which increments the value of the first argument x by one and modulates it with the value of the 2nd argument max.

...

In this case, the programmer intends to increment index and then use that as a value by adding 2 to it. Unfortunately, the value is equal to the incremented value of index because of the semicolon present at the end of the macro. The '+ 2;' is treated as a separate statement by the compiler. The user will not get any compilation errors. If the user has not enabled warnings while compiling, the effect of the semicolon in the macro cannot be detected at an early stage.

Compliant Solution

The compliant solution is to write the macro definition without the semicolon at the end, leaving the decision to have a semicolon or not up to the person who is using the macro.

Code Block
bgColor#CCCCFF
#define INCREMENT(x, max) ((x) = ((x) + 1) % (max))

Risk Assessment

Using a semicolon at the end of a macro definition can result in the change of program control flow and thus unintended program behavior.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

PRE11-C

medium

probable

low

P12

L1

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Other Languages

This rule appears in the C++ Secure Coding Standard as PRE11-CPP. Do not conclude a single statement macro definition with a semicolon.

...