exponenta event banner

CERT C++: OOP57-CPP

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

Описание

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

Предпочтите специальные функции-члены и перегруженные операторы функциям библиотеки C Standard Library. [1 ]

Внедрение Polyspace

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

Примеры

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

Проблема

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

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

  • std::memset

  • std::memcpy

  • std::strcpy

  • std::memmove

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

  • std::memcmp

  • std::strcmp

Операции 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)); 
      // ...
   }
}

Риск

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

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

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

Для выполнения байтовых операций нетривиальных или нестандартных объектов типа класса макета используйте эти специальные функции-члены C++ вместо функций библиотеки C Standard.

Стандартные библиотечные функции 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 после первой инициализации с помощью конструктора по умолчанию. Эта байтовая операция может неправильно инициализировать представление значения 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. Объектно-ориентированное программирование (ООП)
Представлен в R2019b

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

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

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