CERT C++: OOP57-CPP

Предпочтите специальные функции членства и перегруженные операторы к Стандартным Библиотечным функциям C

Описание

Управляйте определением

Предпочтите специальные функции членства и перегруженные операторы к Стандартной Библиотеке C functions.[1]

Реализация Polyspace

Это средство проверки проверяет на операции Bytewise на нетривиальном объекте класса.

Примеры

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

Проблема

Операции Bytewise на нетривиальном объекте класса происходят, когда вы используете Стандартные библиотечные функции C, чтобы выполнить bytewise операцию на нетривиальных или нестандартных текстовых объектах класса макета. Для определений тривиальных и стандартных классов макета см. Стандарт C++, [класс], абзацы 6 и 7 соответственно.

Средство проверки повышает дефект, вы инициализируете или копируете нетривиальные объекты типа класса с помощью этих функций:

  • std::memset

  • std::memcpy

  • std::strcpy

  • std::memmove

Или когда вы сравниваете нестандартные текстовые объекты класса макета с помощью этих функций:

  • std::memcmp

  • std::strcmp

Операции Bytewise на нетривиальном объекте класса не повышают дефекта, если bytewise операция выполняется через псевдоним. Например, никакой дефект не повышен в bytewise сравнении и операциях копии в этом коде. bytewise операции используют dptr и sptr, псевдонимы нетривиального или нестандартного класса макета возражают d и s.

void func(NonTrivialNonStdLayout *d, const NonTrivialNonStdLayout *s)
{
   void* dptr = (void*)d; 
   const void* sptr = (void*)s;
   // ...
   // ...
   // ...
   if (!std::memcmp(dptr, sptr, sizeof(NonTrivialNonStdLayout))) {  
     (void)std::memcpy(dptr, sptr, sizeof(NonTrivialNonStdLayout)); 
      // ...
   }
}

Риск

Выполнение bytewise операции сравнения при помощи Стандартных библиотечных функций C на нетривиальном или нестандартном текстовом объекте класса макета может привести к неожиданным значениям из-за деталей реализации. Объектное представление зависит от деталей реализации, таких как порядок частных и общедоступных членов или использование таблиц указателя виртуальной функции, чтобы представлять объект.

Выполнение bytewise установка операций при помощи Стандартных библиотечных функций C на нетривиальном или нестандартном текстовом объекте класса макета может изменить детали реализации. Операция может привести к аварийному поведению программы или уязвимости выполнения кода. Например, если адрес функции членства перезаписывается, вызов этой функции вызывает неожиданную функцию.

Фиксация

Чтобы выполнить bytewise операции нетривиальный или нестандартный текстовый объект класса макета, используйте их C++ специальные функции членства вместо Стандартных библиотечных функций C.

C стандартные библиотечные функцииФункции членства C++

std::memset

Конструктор класса

std::memcpy

std::strcpy

std::memmove

Конструктор копии класса

Конструктор перемещения класса

Копирование оператора присваивания

Перемещение оператора присваивания

std::memcmp

std::strcmp

operator<()

operator>()

operator==()

operator!=()

Пример - Используя memset с нетривиальным объектом класса
#include <cstring>
#include <iostream>
#include <utility>

class nonTrivialClass
{
    int scalingFactor;
    int otherData;
public:
    nonTrivialClass() : scalingFactor(1) {}
    void set_other_data(int i);
    int f(int i)
    {
        return i / scalingFactor;
    }
    // ...
};

void func()
{
    nonTrivialClass c;
    // ... Code that mutates c ...
    std::memset(&c, 0, sizeof(nonTrivialClass));
    std::cout << c.f(100) << std::endl;
}

В этом примере, func() использование std::memset повторно инициализировать нетривиальный объект класса c после того, как это сначала инициализируется своим конструктором по умолчанию. Эта bytewise операция не может правильно инициализировать представление значения c.

Коррекция — задает шаблон функции, который использует std::swap

Одна возможная коррекция должна задать шаблон функции clear() это использует std::swap выполнять операцию подкачки. Вызов clear()правильно повторно инициализирует объект c путем свопинга содержимого c и значение по умолчанию инициализировало объект empty.

 #include <cstring>
#include <iostream>
#include <utility>

class nonTrivialClass
{
    int scalingFactor;
    int otherData;
public:
    nonTrivialClass() : scalingFactor(1) {}
    void set_other_data(int i);
    int f(int i)
    {
        return i / scalingFactor;
    }
    // ...
};

template <typename T>
T& clear(T& o)
{
    using std::swap;
    T empty;
    swap(o, empty);
    return o;
}

void func()
{
    nonTrivialClass c;
    // ... Code that mutates c ...

    clear(c);
    std::cout << c.f(100) << std::endl;
}

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

Группа: правило 09. Объектно-ориентированное программирование (OOP)
Введенный в R2019b

[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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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