CERT C: Rec. DCL07-C

Включите соответствующую информацию о типах в объявления функций

Описание

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

Включите соответствующую информацию о типе в объявления функций.[1]

Реализация Polyspace

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

  • Переключение между указателями на функцию с различными типами.

  • Функция объявлена неявно.

Примеры

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

Проблема

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

Polyspace® рассматривает как явные, так и неявные приведения при проверке этого правила. Однако отливки из NULL или (void*)0 не нарушать это правило.

Риск

Правило запрещает следующие два преобразования:

  • Преобразование указателя на функцию в любой другой тип. Это преобразование вызывает неопределенное поведение.

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

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

Пример - Приведение между двумя указателями на функцию
typedef void (*fp16) (short n);
typedef void (*fp32) (int n);

#include <stdlib.h>                     /* To obtain macro  NULL */

void func(void) {   /* Exception 1 - Can convert a null pointer 
                     * constant into a pointer to a function */
  fp16 fp1 = NULL;                 /* Compliant - exception  */
  fp16 fp2 = (fp16) fp1;           /* Compliant */
  fp32 fp3 = (fp32) fp1;           /* Non-compliant */
  if (fp2 != NULL) {}              /* Compliant - exception  */
  fp16 fp4 = (fp16) 0x8000;        /* Non-compliant - integer to 
                                    * function pointer */}

В этом примере правило нарушается, когда:

  • Указатель fp1 типа fp16 приведен к типу fp32. Тип указателя на функцию fp16 и fp32 имеют различные типы аргументов.

  • Целое число приведено к типу fp16.

Правило не нарушается, когда указатели на функцию fp1 и fp2 приведены к NULL.

Проблема

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

Риск

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

Пример - Функция, не объявленная перед вызовом
#include <math.h>

extern double power3 (double val, int exponent);
int getChoice(void);

double func() {
    double res;
    int ch = getChoice();
    if(ch == 0) {
        res = power(2.0, 10);    /* Non-compliant */
    }
    else if( ch==1) {
        res = power2(2.0, 10);   /* Non-compliant */
    }
    else {
        res = power3(2.0, 10);   /* Compliant */
        return res;
    }
}

double power2 (double val, int exponent) {
    return (pow(val, exponent));
}

В этом примере правило нарушается, когда в коде вызывается функция, которая не объявлена. Даже если определение функции существует позже в коде, происходит нарушение правила.

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

  • Объявите функцию с extern ключевое слово в текущем файле.

  • Объявить функцию в заголовочном файле и включить заголовочный файл в текущий файл.

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

Группа: Рек. 02. Объявления и инициализация (DCL)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.