Вызовите функции с правильным номером и типом аргументов
Проблема происходит, когда вы вызываете функцию, прежде чем вы объявите или зададите ее.
Неявное объявление происходит, когда вы вызываете функцию прежде, чем объявить или задать его. Когда вы объявляете функцию явным образом прежде, чем вызвать его, компилятор может совпадать с аргументом и возвратить типы с типами параметра в объявлении. Если неявное объявление происходит, компилятор делает предположения об аргументе, и возвратите типы. Например, это принимает тип возврата 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
в текущем файле.
Объявите функцию в заголовочном файле и включайте заголовочный файл в текущий файл.
Плохой режим доступа к файлу или состояние происходят, когда вы используете функции в fopen
или группе open
с недопустимыми или несовместимыми режимами доступа к файлу, флагами создания файла или флагами состояния файла в качестве аргументов. Например, для функции open
, примеров допустимых:
Режимы доступа включают O_RDONLY
, O_WRONLY
и O_RDWR
Флаги создания файла включают O_CREAT
, O_EXCL
, O_NOCTTY
и O_TRUNC
.
Флаги состояния файла включают O_APPEND
, O_ASYNC
, O_CLOEXEC
, O_DIRECT
, O_DIRECTORY
, O_LARGEFILE
, O_NOATIME
, O_NOFOLLOW
, O_NONBLOCK
, O_NDELAY
, O_SHLOCK
, O_EXLOCK
, O_FSYNC
, O_SYNC
и так далее.
Дефект может произойти в следующих ситуациях.
Ситуация | Риск | Фиксация |
---|---|---|
Вы передаете пустой или недопустимый режим доступа функции Согласно стандарту ANSI® C, допустимые режимы доступа для
|
Некоторые реализации позволяют расширение режима доступа, такого как:
Однако ваша строка режима доступа должна начаться с одной из допустимых последовательностей. | Передайте допустимый режим доступа fopen . |
Вы передаете флаг O_APPEND состояния функции open , не комбинируя его или с O_WRONLY или с O_RDWR . |
Функция | Передайте или O_APPEND|O_WRONLY или O_APPEND|O_RDWR как режим доступа. |
Вы передаете флаги состояния O_APPEND и O_TRUNC вместе к функции open . |
Функция | В зависимости от того, что вы намереваетесь сделать, передайте один из этих двух режимов. |
Вы передаете флаг O_ASYNC состояния функции open . | На определенных реализациях режим O_ASYNC не включает управляемые сигналом операции I/O. | Используйте fcntl(pathname, F_SETFL, O_ASYNC); вместо этого. |
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
fopen
#include <stdio.h>
void func(void) {
FILE *file = fopen("data.txt", "rw");
if(file!=NULL) {
fputs("new data",file);
fclose(file);
}
}
В этом примере режим доступа rw
недопустим. Поскольку r
указывает, что вы открываете файл для чтения, и w
указывает, что вы создаете новый файл для записи, эти два режима доступа несовместимы.
r
или w
как режим доступаОдно возможное исправление должно использовать соответствие режима доступа, что вы намереваетесь сделать.
#include <stdio.h> void func(void) { FILE *file = fopen("data.txt", "w"); if(file!=NULL) { fputs("new data",file); fclose(file); } }
Ненадежный бросок указателя функции происходит, когда указатель функции брошен к другому указателю функции, который имеет различный аргумент, или возвратите тип.
Этот дефект применяется, только если кодовый язык для проекта является 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; }
Вызов стандартной функции с неправильными аргументами происходит, когда аргументы к функциям определенного стандарта не удовлетворяют требования для своего использования в функциях.
Например, аргументы к этим функциям могут быть недопустимыми следующими способами.
Функциональный тип | Ситуация | Риск | Фиксация |
---|---|---|---|
Обработка строк функционирует, такие как strlen и strcpy | Аргументы указателя не указывают на NULL - отключенная строка. | Поведение функции не определено. | Передайте NULL - отключенная строка к функциям обработки строк. |
Обработка файла функционирует в stdio.h , таком как fputc и fread | Аргумент указателя FILE* может иметь значение NULL . | Поведение функции не определено. | Протестируйте указатель FILE* на NULL перед использованием его как аргумент функции. |
Обработка файла функционирует в unistd.h , таком как lseek и read | Аргумент дескриптора файла может быть-1. | Поведение функции не определено. Большинство реализаций функции | Протестируйте возвращаемое значение функции Если возвращаемое значение-1, проверяйте значение |
Аргумент дескриптора файла представляет закрытый дескриптор файла. | Поведение функции не определено. | Закройте дескриптор файла только после того, как вы полностью закончите использовать его. Также вновь откройте дескриптор файла перед использованием его как аргумент функции. | |
Генерация имени каталога функционирует, такие как mkdtemp и mkstemps | Последними шестью символами шаблона строки не является XXXXXX . | Функция заменяет последние шесть символов на строку, которая делает имя файла уникальным. Если последними шестью символами не является XXXXXX , функция не может сгенерировать достаточно уникальное имя каталога. | Протестируйте, если последними шестью символами строки является XXXXXX перед использованием строки как аргумент функции. |
Функции, связанные с переменными окружения, такими как getenv и setenv | Аргументом строки является "" . | Поведение задано реализацией. | Протестируйте аргумент строки на "" перед использованием его в качестве аргумента getenv или setenv . |
Аргумент строки останавливается со знаком "равно", = . Например, "C=" вместо "C" . | Поведение задано реализацией. | Не отключайте аргумент строки с = . | |
Представьте в виде строки функции обработки, такие как strtok и strstr |
| Некоторые реализации не обрабатывают эти случаи ребра. | Протестируйте строку для "" перед использованием его как аргумент функции. |
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
NULL
, пройден в качестве аргумента strnlen
#include <string.h>
#include <stdlib.h>
enum {
SIZE10 = 10,
SIZE20 = 20
};
int func() {
char* s = NULL;
return strnlen(s, SIZE20);
}
В этом примере указатель NULL
передается в качестве аргумента strnlen
вместо NULL
- отключенная строка.
Перед рабочим анализом кода задайте компилятор GNU. Смотрите Compiler (-compiler)
.
NULL
- отключенная строкаПередайте NULL
- отключенная строка в качестве первого аргумента strnlen
.
#include <string.h> #include <stdlib.h> enum { SIZE10 = 10, SIZE20 = 20 }; int func() { char* s = ""; return strnlen(s, SIZE20); }
Группа: правило 03. Выражения (EXP) |
[1] Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.
ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.
Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.