メインコンテンツ

CERT C: Rec.PRE10-C

マルチステートメント マクロを do-while ループでラップする

説明

ルール定義

マルチステートメント マクロを do-while ループでラップします。1

Polyspace 実装

ルール チェッカーは、"マクロに複数のステートメントがあります" をチェックします。

すべて展開する

問題

[マクロに複数のステートメントがあります] は、ステートメントが中かっこで囲まれているかどうかに関係なく、マクロにセミコロンで終了する複数のステートメントが含まれている場合に発生します。

リスク

if 条件やループなどの特定のコンテキストでのマクロ展開は、不明なプログラム ロジックにつながる可能性があります。

たとえば、次のマクロを考えてみましょう。

#define RESET(x,y) \
   x=0; \
   y=0;
次のような if ステートメントでは、
if(checkSomeCondition)
   RESET(x,y);
マクロが次のように展開されます。
if(checkSomething)
   x=0;
y=0;
これは、if ブロックで両方のステートメントが実行された場合に予期せぬ結果を招く可能性があります。

修正方法

マクロ定義で、複数のステートメントを do...while(0) ループでラップします。

たとえば、前述の例では、次の定義を使用します。

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)
このマクロは、あらゆるコンテキストでの展開に適しています。while(0) は、ステートメントが 1 回しか実行されないようにします。

または、複数のステートメントを呼び出す関数形式マクロよりインライン関数を使用します。

正しい解決策にはループが必須であり、中かっこでステートメントをラップしただけでは問題は解決されないことに注意してください。マクロ展開は意図しないコードにつながる可能性があります。

例 – 複数のステートメントからなるマクロ
#define RESET(x,y) \ //Noncompliant
   x=0; \
   y=0;

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

この例では、マクロ RESET が複数のステートメントで構成されているために不具合が発生します。

修正 – マクロの複数のステートメントを do-while ループでラップする

マクロのステートメントをマクロ定義内の do..while(0) ループでラップします。

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

チェック情報

グループ: Rec.01.プリプロセッサ (PRE)

バージョン履歴

R2020a で導入


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.