メインコンテンツ

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

CERT C: Rule MSC38-C

マクロとして実装されている可能性のある定義済みの識別子をオブジェクトとして扱わない

説明

ルール定義

マクロとして実装されている可能性のある定義済みの識別子をオブジェクトとして扱わないようにします。1

Polyspace 実装

ルール チェッカーは、"オブジェクトとして使用される事前定義されたマクロ" をチェックします。

すべて展開する

問題

[オブジェクトとして使用される事前定義されたマクロ] は、基になるオブジェクトの存在が必要な方法で、特定の識別子を使用する場合に発生します。これらの識別子はマクロとして定義されます。C 標準では、これらをオブジェクトとして再定義することは許可されていません。識別子のマクロ展開が発生する可能性がないような方法で識別子を使用します。

たとえば、外部変数 errno を参照します。

extern int errno;
しかし、errno は変数ではなくマクロとして発生します。

この欠陥が当てはまるマクロは、asserterrnomath_errhandlingsetjmpva_argva_copyva_end、および va_start です。チェッカーは、(ヘッダー ファイルではなく) ソース ファイル内にある欠陥のみを調べます。

リスク

C11 規格 (節 7.1.4) では、ほとんどのマクロをオブジェクトとして再定義することが許可されています。ソース ファイルのオブジェクトにアクセスし、マクロにアクセスしないようにするには、以下のいずれかを行います。

  • 識別子を外部変数または関数として再宣言する。

  • 関数形式のマクロについては、識別子名を小かっこで囲む。

オブジェクトとして再定義できないマクロにこれらの手法を使用しようとすると、エラーが発生します。

修正方法

マクロ展開が抑制されるような方法で識別子を使用しないようにします。

  • 識別子を外部変数または関数として再宣言しない。

  • 関数形式のマクロについては、マクロ名を小かっこで囲まない。

例 - 関数としての assert の使用
#include<assert.h>
typedef void (*err_handler_func)(int);

extern void demo_handle_err(err_handler_func, int);

void func(int err_code) {
    extern void assert(int);    //Noncompliant
    demo_handle_err(&(assert), err_code); //Noncompliant
}

この例では、assert マクロが外部関数として再定義されています。demo_handle_err に引数として渡されると、識別子 assert が小かっこで囲まれることにより、assert マクロの使用が抑制されます。

修正 — assert をマクロとして使用

1 つの修正方法として、assert.h から assert マクロを直接使用します。関数 demo_handle_err の別の実装で、関数 assert のアドレスを取得するのではなく、assert を直接使用します。

#include<assert.h>
void demo_handle_err(int err_code) {
    assert(err_code == 0);                   
}

void func(int err_code) {
    demo_handle_err(err_code);          
}

チェック情報

グループ: Rule 48.その他 (MSC)

バージョン履歴

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.