メインコンテンツ

ISO/IEC TS 17961 [argcomp]

Calling functions with incorrect arguments

説明

ルール定義

不適切な引数での関数の呼び出し。1

Polyspace 実装

このチェッカーは以下の問題をチェックします。

  • 宣言の間の競合または宣言と定義の間の競合

  • 関数ポインターの信頼性の低いキャスト

すべて展開する

問題

この問題は、オブジェクトまたは関数のすべての宣言で同じ名前と型修飾子を使用しない場合に発生します。

ルール チェッカーは、パラメーター名またはデータ型が、複数の宣言の間または宣言と定義の間で異なっている状況を検出します。チェッカーは、すべての翻訳単位内の宣言を考慮し、コンパイラによって検出されない可能性のある問題にフラグを設定します。

既定の Polyspace® as You Code 解析では、チェッカーはこの問題にフラグを設定しませんPolyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください

リスク

同一のオブジェクトまたは関数の宣言全体で、常にパラメーター名と型を使用すると、より厳密な型指定となります。すべての宣言で同じ関数インターフェイスが使用されていることを容易にチェックできるようになります。

例 - パラメーターの名前の不一致
extern int div (int num, int den);

int div(int den, int num) { /* Non compliant */
    return(num/den);
}

この例では、宣言と定義内のパラメーター名が入れ替わっているため、ルールに違反しています。

例 - パラメーターのデータ型の不一致
typedef unsigned short width;
typedef unsigned short height;
typedef unsigned int area;

extern area calculate(width w, height h);

area calculate(width w, width h) { /* Noncompliant */
    return w*h;
}

この例では、関数 calculate の 2 番目の引数が次のデータ型であるため、ルールに違反しています。

  • 宣言内では height

  • 定義内では width

height および width の潜在型が同一である場合も、ルールに違反しています。

問題

関数ポインターの信頼性の低いキャストは、関数ポインターが引数または戻り値の型が異なる別の関数ポインターにキャストされる場合に発生します。

この欠陥は、プロジェクトのコード言語が C の場合にのみ当てはまります。

リスク

関数ポインターを引数または戻り値の型が異なる別の関数ポインターにキャストし、後者の関数ポインターを使用して関数を呼び出した場合、動作は未定義になります。

修正方法

引数または戻り値の型が一致しない 2 つの関数ポインター間のキャストは避けます。

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 関数ポインターの信頼性の低いキャスト エラー
#include <stdio.h>
#include <math.h>
#include <stdio.h>
#define PI 3.142
 
double Calculate_Sum(int (*fptr)(double))
{
    double  sum = 0.0;
    double  y;
	  
    for (int i = 0;  i <= 100;  i++)
    {
        y = (*fptr)(i*PI/100);
        sum += y;
    }
    return sum / 100;
}
 
int main(void)
{
    double  (*fp)(double);      
    double  sum;
 
    fp = sin;
    sum = Calculate_Sum(fp); 
    /* Defect: fp implicitly cast to int(*) (double) */

    printf("sum(sin): %f\n", sum);
    return 0;
}

関数ポインター fpdouble (*)(double) として宣言されています。しかし、関数 Calculate_Sum に渡す時に fp は暗黙的に int (*)(double) にキャストされます。

修正 — 関数ポインターのキャストを回避

1 つの修正方法として、Calculate_Sum の定義における関数ポインターが、fp と同じ引数および戻り値の型をもつことをチェックすることができます。このステップにより、fp が異なる引数または戻り値の型に暗黙的にキャストされないことが保証されます。

#include <stdio.h>
#include <math.h>
#include <stdio.h>
# define PI 3.142
 
/*Fix: fptr has same argument and return type everywhere*/
double Calculate_Sum(double (*fptr)(double)) 
{
    double  sum = 0.0;
    double y;
	    
    for (int i = 0;  i <= 100;  i++)
    {
        y = (*fptr)(i*PI/100);
        sum += y;
    }
    return sum / 100;
}
 
int main(void)
{
    double  (*fp)(double);      
    double  sum;
 
    
    fp = sin;
    sum = Calculate_Sum(fp);
    printf("sum(sin): %f\n", sum);
 
    return 0;
}

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.