メインコンテンツ

AUTOSAR C++14 Rule A6-5-3

Do statements should not be used

説明

ルール定義

Do statements should not be used.

根拠

do ステートメントの終了条件はコード ブロックの実行後にチェックされるため、このステートメントを使用するとコード内のバグにつながる可能性があります。do-while ループ内でポインターを使用して配列にアクセスする、次のコードについて考えます。

int* array;
//...
do {
cout<<*array;
--array;
} while (array != nullptr); 
コード ブロックの実行後に終了条件がチェックされることから、このコードは無効なポインターまたは NULL ポインターをデリファレンスする可能性があります。これにより、実行中にコードの実行が予期せずに終了する可能性があります。また、ブロックの実行条件が見逃しやすいブロック末尾にあるため、読みにくいコードにもなっています。

コード内での do ステートメントの使用を避けてください。do ステートメントを使用して、関数形式のマクロを作成できます。

Polyspace 実装

Polyspace® は、マクロ内にあるものを除き、すべての do ステートメントにフラグを設定します。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

この例は、Polyspace がマクロ外部にある do ステートメントにフラグを設定する仕組みを説明しています。このコードでは、do-while ループ内でポインターを使用しています。終了条件は、ポインターが NULL ポインターではないことです。

#include<cstdint>
struct P
{
	int val;
	struct P* next;
};

void psKO(P*p)
{
	do              // Noncompliant
	{
		p = p->next;
	} while(p!=nullptr);
}

終了条件は do ブロックの実行後にチェックされるため、このコードは NULL ポインターをデリファレンスする可能性があります。また、ブロックの実行条件が、見逃しやすいブロック末尾にあるため、読みにくいコードにもなっています。Polyspace は do ステートメントにフラグを設定します。

この例は、Polyspace がマクロ内の do ステートメントを扱う方法を説明しています。マクロ SWAPSWAP2 の 2 つが実装されている次のコードを考えます。SWAP では do ステートメントが使用されていますが、SWAP2 では使用されていません。

#include <cstdint>
//Compliant by exception 
#define SWAP(a, b) \
        do                         \
        {                          \
            decltype(a) tmp = (a); \
           (a) = (b);             \
           (b) = tmp;             \
       } while (0)

#define SWAP2(a, b)        \
       decltype(a) tmp = (a); \
       (a) = (b);             \
       (b) = tmp;

int main(void)
{
  uint8_t a = 24;
  uint8_t b = 12;

  if (a > 12)
//  SWAP2(a, b);  // Compilation Error
  SWAP(a, b);
return 0;
}

この 2 つのマクロは、関数のように呼び出されることが意図されています。if ブロック内では SWAP2 を関数型のマクロとして使用することはできません。これは、マクロ展開後に if ブロックに残っているのが SWAP2 の最初の式ステートメントのみであるためです。このようにマクロを分割することで、マクロの意味が変化します。この例の場合は、コンパイル エラーが発生します。この問題を解決するには、マクロを do-while ブロック内に収容して、終了条件を false として設定します。このように収容されたマクロを分割することはできないため、マクロを関数として呼び出すことができます。Polyspace はマクロ内の do ステートメントにはフラグを設定しません。

チェック情報

グループ: ステートメント
カテゴリ: Advisory、Automated

バージョン履歴

R2020b で導入