Main Content

CERT C++: EXP52-CPP

Do not rely on side effects in unevaluated operands

Description

Rule Definition

Do not rely on side effects in unevaluated operands.1

Polyspace Implementation

The rule checker checks for the following:

  • Logical operator operand with side effects

  • sizeof, alignof or decltype operand with side effects

Examples

expand all

Issue

The issue occurs when the right hand operand of a logical && or || operator contains side effects. When evaluated, an expression with side effect modifies at least one of the variables in the expression.

The checker does not consider volatile accesses and function calls as potential side effects.

Risk

When evaluated, an expression with side effect modifies at least one of the variables in the expression. For instance, n++ is an expression with side effect.

The right-hand operand of a:

  • Logical && operator is evaluated only if the left-hand operand evaluates to true.

  • Logical || operator is evaluated only if the left-hand operand evaluates to false.

In other cases, the right-hand operands are not evaluated, so side effects of the expression do not take place. If your program relies on the side effects, you might see unexpected results in those cases.

Fix

If you want the expression in the right-hand operand evaluated, perform the evaluation in a separate statement.

For instance, instead of:

if(isOK && n++) {}
perform the operation in two steps:
n++;
if(isOK && n) {}

Issue

This issue occurs when the sizeof, alignof or decltype operator operates on an expression with a side effect. When evaluated, an expression with side effect modifies at least one of the variables in the expression.

For instance, the defect checker does not flag sizeof(n+1) because n+1 does not modify n. The checker flags sizeof(n++) because n++ is intended to modify n.

Risk

Side effects in an alignof operator or decltype operator do not persist beyond the operation. The expression in a sizeof operator is evaluated only if it is required for calculating the size of a variable-length array, for instance, sizeof(a[n++]).

When an expression with a side effect is not evaluated, the variable modification from the side effect does not happen. If you rely on the modification, you can see unexpected results.

Fix

Evaluate the expression with a side effect in a separate statement, and then use the result in a sizeof, _Alignof, or _Generic operator.

For instance, instead of:

a = sizeof(n++);
perform the operation in two steps:
n++;
a = sizeof(n);

The checker considers a function call as an expression with a side effect. Even if the function does not have side effects now, it might have side effects on later additions. The code is more maintainable if you call the function outside the sizeof operator. If you call a function in a decltype, for instance, to select the correct overload of a function and then determine its return type, the checker considers such a call as an exception.

Example – Increment Operator in sizeof
#include <stdio.h>

void func(void) {
    unsigned int a = 1U;
    unsigned int b = (unsigned int)sizeof(++a); //Noncompliant
    printf ("%u, %u\n", a, b);
}

In this example, sizeof operates on ++a, which is intended to modify a. Because the expression is not evaluated, the modification does not happen. The printf statement shows that a still has the value 1.

Correction — Perform Increment Outside sizeof

One possible correction is to perform the increment first, and then provide the result to the sizeof operator.

#include <stdio.h>

void func(void) {
    unsigned int a = 1U;
    ++a;
    unsigned int b = (unsigned int)sizeof (a); 
    printf ("%u, %u\n", a, b);
}

Check Information

Group: 02. Expressions (EXP)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.