メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C: Rule EXP44-C

sizeof、_Alignof、または _Generic のオペランドの二次的影響に依存しない

説明

ルール定義

sizeof、_Alignof、または _Generic のオペランドの二次的影響に依存しないようにします。1

Polyspace 実装

ルール チェッカーは、"式の二次的影響は無視されます" をチェックします。

すべて展開する

問題

[式の二次的影響は無視されます] は、sizeof_Alignof、または _Generic 演算子が二次的影響のある式に対して実行される場合に発生します。評価されると、二次的影響のある式はその式内の 1 つ以上の変数を変更します。

たとえば、n+1 では n が変更されないため、欠陥チェッカーは sizeof(n+1) にフラグを設定しません。n++n を変更することを意図しているため、チェッカーは sizeof(n++) にはフラグを設定します。

このチェッカーは C++ の演算子 alignof と、その C 拡張 __alignof__ および __typeof__ にも適用されます。

リスク

_Alignof または _Generic 演算子の式は評価されません。sizeof 演算子の式は、sizeof(a[n++]) など、可変長配列のサイズを計算するためにそれが必要な場合に限り評価されます。

二次的影響のある式が評価されない場合、二次的影響による変数の変更は発生しません。その変更に依存している場合、予期しない結果になる可能性があります。

修正方法

別のステートメントで二次的影響のある式を評価してから、sizeof_Alignof、または _Generic 演算子でその結果を使用します。

たとえば、以下のようにはしません。

a = sizeof(n++);
次の 2 ステップで演算を実行します。
n++;
a = sizeof(n);

チェッカーは、関数呼び出しを二次的影響のある式と見なします。現在は関数に二次的影響がない場合でも、後の加算に対して二次的影響をもつ可能性があります。関数を sizeof 演算子の外部で呼び出すと、コードの保守が容易になります。

例 - 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);
}

この例では、a を変更することを目的とした ++a に対して sizeof を実行しています。式が評価されないため、変更は発生しません。printf ステートメントにより、a の値が 1 のままであることが示されます。

修正 — sizeof の外部でインクリメントを実行

1 つの修正方法として、最初にインクリメントを実行してから、その結果を sizeof 演算子に渡します。

#include <stdio.h>

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

チェック情報

グループ: Rule 03.式 (EXP)

バージョン履歴

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.