Main Content

Side effect of expression ignored

sizeof, _Alignof, or _Generic operates on expression with side effect

Description

This defect 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.

Examples

expand all

#include <stdio.h>

void func(void) {
    unsigned int a = 1U;
    unsigned int b = (unsigned int)sizeof(++a);
    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);
}

Result Information

Group: Programming
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: SIDE_EFFECT_IGNORED
Impact: Low

Version History

Introduced in R2018a