MISRA C:2012 Rule 21.16

Аргументы указателя на функцию Standard Library memcmp должен указывать либо на тип указателя, по существу на тип со знаком, по существу беззнаковый тип, по существу на логический тип или по существу на тип перечисления

Описание

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

Аргументы указателя на функцию Standard Library memcmp должен указывать либо на тип указателя, по существу на тип со знаком, по существу беззнаковый тип, по существу на логический тип или по существу на тип перечисления.

Это правило получено от MISRA C®: 2012 1 о внесении изменений.

Объяснение

Функция «Стандартная библиотека»

memcmp ( lhs, rhs, num );
выполняет байтовое сравнение первого num байты двух объектов, которые lhs и rhs указать на.

Не используйте memcmp для сравнения байт/байт следующего.

НапечататьОбъяснение
Структуры Если представители структуры имеют различные типы данных, ваш компилятор вводит дополнительное заполнение для выравнивания данных в памяти. Содержимое этих дополнительных байтов заполнения бессмысленно. Если вы выполняете байтовое сравнение структур с memcmp, вы сравниваете даже бессмысленные данные, хранящиеся в заполнении. Вы можете прийти к ложному выводу, что две структуры данных не равны, даже если их соответствующие представители имеют одинаковое значение.
Объекты с плавающим типомОдно и то же значение с плавающей точкой может храниться с помощью различных представлений. Если вы выполняете байтовое сравнение двух переменных с memcmpможно прийти к ложному выводу, что переменные неравны, даже когда они имеют одно и то же значение. Причина в том, что значения хранятся с помощью двух различных представлений.
По сути, char arraysПо существу, массивы char обычно используются для хранения строк. В строках содержимое в байтах после null terminator бессмысленно. Если вы выполняете байтовое сравнение двух строк с memcmp, вы можете прийти к ложному выводу, что две строки не равны, даже если байты перед null terminator сохраняют одно и то же значение.

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

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

#include <stdbool.h>
#include <stdint.h>

struct S {
//...
};

bool f1(struct S* s1, struct S* s2)
{
    return (memcmp(s1, s2, sizeof(struct S)) != 0); /* Non-compliant */
}

union U {
    uint32_t range;
    uint32_t height;
};
bool f2(union U* u1, union U* u2)
{
    return (memcmp(u1, u2, sizeof(union U)) != 0); /* Non-compliant */
}

const char a[ 6 ] = "task";
bool f3(const char b[ 6 ])
{
    return (memcmp(a, b, 6) != 0); /* Non-compliant */
}

В этом примере:

  • Структурные s1 и s2 сравниваются в bool_t f1 функция. Возврат значение этой функции может указывать, что s1 и s2 отличаются из-за заполнения. Это сравнение несовместимо.

  • Объединения u1 и u2 сравниваются в bool_t f2 функция. Возврат значение этой функции может указывать, что u1 и u2 являются одинаковыми из-за непреднамеренного сравнения u1.range и u2.height, или u1.height и u2.range. Это сравнение несовместимо.

  • По сути, массивы char a и b сравниваются в bool_t f3 функция. Возврат значение этой функции может неправильно указать, что строки различаются, потому что длина a (четыре) меньше, чем количество байтов по сравнению (шесть). Это сравнение несовместимо.

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

Группа: Стандартные библиотеки
Категория: Требуемая
Категория AGC: Требуется
Введенный в R2017a