ISO/IEC TS 17961 [argcomp]

Вызов функций с неправильными аргументами

Описание

Определение правила

Вызов функций с неправильными аргументами.[1]

Реализация Polyspace

Эта проверка проверяет на наличие следующих проблем:

  • Конфликтующие объявления или противоречивое объявление и определение.

  • Ненадежное приведение указателя на функцию.

Примеры

расширить все

Проблема

Проблема возникает, когда все объявления объекта или функции не используют одинаковые имена и типы квалификаторов.

Средство проверки правил обнаруживает ситуации, когда имена параметров или типы данных отличаются между несколькими объявлениями или объявлением и определением. Чекер рассматривает объявления во всех модулях перевода и проблемы с флагами, которые не могут быть обнаружены компилятором.

Polyspace® Bug Finder™ и Polyspace Code Prover™ по-разному проверить это правило кодирования. Анализы могут привести к различным результатам.

Чекер не помечает эту проблему в Polyspace по умолчанию во время анализа You Code. Смотрите Checkers Deactivated in Polyspace как You Code Default Analysis (Polyspace Bug Finder 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 функция имеет тип данных:

  • height в декларации.

  • width в определении.

Правило нарушается, хотя базовый тип height и width идентичны.

Проблема

Ненадежное приведение указателя на функцию происходит, когда указатель на функцию приведен к другому указателю на функцию, который имеет другой аргумент или возвращаемый тип.

Этот дефект применяется только в том случае, если языком кода для проекта является C.

Риск

Если вы приведете указатель на функцию к другому указателю на функцию с другим аргументом или возвращаемым типом, а затем используете последний указатель на функцию для вызова функции, поведение не определено.

Зафиксировать

Избегайте приведения между двумя указателями на функцию с несовпадением аргументов или возвращаемых типов.

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

Пример - Ненадежное приведение ошибки указателя на функцию
#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;
}

Указатель на функцию fp объявлен как double (*)(double). Однако, проходя его, чтобы функционировать Calculate_Sum, fp неявно приведено к int (*)(double).

Коррекция - Избегайте приведения указателя на функцию

Одной из возможных коррекций является проверка того, что указатель на функцию в определении 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;
}

Проверяйте информацию

Решимость: Undecidable
Введенный в R2019a

[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.