メインコンテンツ

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

CERT C++: INT35-C

Use correct integer precisions

説明

ルール定義

整数の適切な精度を使用します。1

Polyspace 実装

ルール チェッカーは、"整数の精度を超過しました" をチェックします。

すべて展開する

問題

整数の精度を超過しましたは、演算での整数式において整数の精度を超過する整数サイズを使用すると発生する可能性があります。一部のアーキテクチャでは、メモリ内の整数サイズに符号とパディング ビットが含まれることがあります。これらのアーキテクチャでは、整数の値相当のビット数にすぎない精度よりも整数サイズの方が大きくなります。

リスク

整数の精度に対する演算に整数サイズを使用すると、整数オーバーフロー、ラップ アラウンド、または予期しない結果を引き起こす可能性があります。たとえば、符号なし整数は 64 ビットのメモリに格納できますが、その値を表現するには 48 ビットのみを使用します。この整数に対する 56 ビット左シフト演算は未定義の動作です。

整数のサイズがその精度と等しいと仮定すると、異なるアーキテクチャ間でプログラム移植性の問題が発生する場合もあります。

修正方法

整数のサイズをその精度の代わりに使用しないようにします。整数の精度を求めるには、精度計算ルーチンを実装するか、__builtin_popcount() などの組み込み関数を使用します。

例 - 左シフト演算に unsigned int のサイズを使用
#include <limits.h>

unsigned int func(unsigned int exp)
{
    if (exp >= sizeof(unsigned int) * CHAR_BIT) {
        /* Handle error */
    }
    return 1U << exp; //Noncompliant
}

この例では、関数は左シフト演算を使用して 2 の exp 乗の値を返します。演算では、1U のビットを左に exp 位置だけシフトします。if ステートメントでは、演算でビットをシフトする位置数 expunsigned int のサイズよりも大きくなっていないことを確認しています。しかし、unsigned int にパディング ビットが含まれる場合、sizeof() により返される値は unsigned int の精度よりも大きくなります。その結果、exp の一部の値が大きくなりすぎる可能性があり、シフト演算が未定義の動作になる場合があります。

修正 — unsigned int の精度を計算する関数を実装

1 つの修正方法として、設定されたビット数をカウントして unsigned int の精度を計算する関数 popcount() を実装します。

#include <stddef.h>
#include <stdint.h>
#include <limits.h>

size_t popcount(uintmax_t);
#define PRECISION(umax_value) popcount(umax_value)


unsigned int func(unsigned int exp)
{
    if (exp >= PRECISION(UINT_MAX)) {
        /* Handle error */
    }
    return 1 << exp;
}




size_t popcount(uintmax_t num)
{
    size_t precision = 0;
    while (num != 0) {
        if (num % 2 == 1) {
            precision++;
        }
        num >>= 1;
    }
    return precision;
} 

チェック情報

グループ: 03.整数 (INT)

バージョン履歴

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.