メインコンテンツ

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

MISRA C:2023 Rule 18.4

The +, -, += and -= operators should not be applied to an expression of pointer type

R2024a 以降

説明

ルール定義

The +, -, += and -= operators should not be applied to an expression of pointer type 1 .

根拠

ポインター演算で推奨される形式は、配列添字構文 ptr[expr] の使用です。この構文は明確でポインター操作よりもエラーが発生しにくくなっています。ポインター操作では、明示的に計算した任意のポインター値により、意図していない、あるいは無効なメモリ アドレスへのアクセスが発生する可能性があります。配列のインデックス付けでも、意図していない、あるいは無効なメモリへのアクセスが発生する可能性はありますが、レビューはこちらの方が容易です。

経験の浅い C プログラマであれば、式 ptr+1ptr のアドレスに 1 をプラスしたものと誤って解釈する可能性があります。ただし、新しいメモリ アドレスはポインターのターゲットのサイズ (バイト数) に依存します。この混同は予期しない動作の原因となります。

注意して使えば、++ によるポインター操作の方が自然です (たとえばメモリ テスト中の場所への連続的なアクセスなど)。

Polyspace 実装

ルール チェッカーは Pointer + IntegerInteger + PointerPointer - Integer などのポインターの演算にフラグを設定します。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

void fun1(void){
    unsigned char arr[10];
    unsigned char *ptr;
    unsigned char index = 0U;
    
    index = index + 1U;   /* Compliant - rule only applies to pointers */
    
    arr[index] = 0U;      /* Compliant */
    ptr = &arr[5];        /* Compliant */
    ptr = arr;
    ptr++;                /* Compliant - increment operator not + */
    *(ptr + 5) = 0U;      /* Non-compliant */
    ptr[5] = 0U;          /* Compliant */
}

この例では、ポインターと配列を使用したさまざまな演算を示しています。この例で唯一準拠していない演算では + 演算子をポインターに直接使用しています (12 行目)。

void fun2(void){
    unsigned char array_2_2[2][2] = {{1U, 2U}, {4U, 5U}};
    unsigned char i = 0U;
    unsigned char j = 0U;
    unsigned char sum = 0U;
    
    for(i = 0u; i < 2U; i++){
        unsigned char *row = array_2_2[ i ];
        
        for(j = 0u; j < 2U; j++){
            sum += row[ j ];                   /* Compliant */    
        }
    }        
}

この例では、2 番目の for ループは演算式内で配列ポインター row を使用しています。ただし、この使用法は配列インデックス形式を使用しているため準拠しています。

void fun3(unsigned char *ptr1, unsigned char ptr2[ ]){
    ptr1++;               /* Compliant */
    ptr1 = ptr1 - 5;      /* Non-compliant */
    ptr1 -= 5;            /* Non-compliant */
    ptr1[2] = 0U;         /* Compliant */
    
    ptr2++;               /* Compliant */
    ptr2 = ptr2 + 3;      /* Non-compliant */
    ptr2 += 3;            /* Non-compliant */
    ptr2[3] = 0U;         /* Compliant */
}

この例ではポインターおよび配列に使用された問題のある演算子を示しています。同じ種類の式がポインターと配列の両方で準拠および非準拠であることに注目してください。

ptr1 が少なくとも 6 つの要素をもつ配列を指さず、ptr2 が少なくとも 4 つの要素をもつ配列を指さない場合、この例はルール 18.1 に違反しています。

チェック情報

グループ: ポインターと配列
カテゴリ: 推奨
AGC カテゴリ: 推奨

バージョン履歴

R2024a で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace® Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.