exponenta event banner

ISO/IEC TS 17961 [argcomp]

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

Описание

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

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

Внедрение Polyspace

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

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

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

Примеры

развернуть все

Проблема

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

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

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

Средство проверки не помечает эту проблему в анализе Polyspace по умолчанию в качестве кода. См. раздел Шашки, деактивированные в Polyspace как анализ кода по умолчанию (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.

Риск

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

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

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

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

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

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

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

Разрешимость: неразрешимая
Представлен в R2019a

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