Main Content

CERT C: Rule EXP44-C

Do not rely on side effects in operands to sizeof, _Alignof, or _Generic

Description

Rule Definition

Do not rely on side effects in operands to sizeof, _Alignof, or _Generic.1

Polyspace Implementation

The rule checker checks for Side effect of expression ignored.

Examples

expand all

Issue

Side effect of expression ignored occurs when the sizeof, _Alignof, or _Generic 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.

The check also applies to the C++ operator alignof and its C extensions, __alignof__ and __typeof__.

Risk

The expression in a _Alignof or _Generic operator is not evaluated. 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.

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: Rule 03. 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.