exponenta event banner

Правило AUTOSAR C++ 14 A18-5-4

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

Описание

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

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

Объяснение

Стандарт C++ 14 определяет версию размера operator delete. Например, для неразмерного operator delete с этой подписью:

void operator delete (void* ptr);
Версия размера имеет дополнительный аргумент размера:
void operator delete (void* ptr, std::size_t size);
См. справочную страницу C++ для operator delete.

Стандарт гласит, что если обе версии operator delete exist, необходимо вызвать версию размера, поскольку она обеспечивает более эффективный способ освобождения памяти. Однако в некоторых случаях, например, для удаления неполных типов, используется неразмерная версия.

При перегрузке неразмерной версии operator delete, необходимо также перегрузить версию размера. Как правило, происходит перегрузка operator delete для выполнения некоторых бухгалтерских операций в дополнение к освобождению памяти в свободном хранилище. Если вы перегружаете неразмерную версию, но не увеличиваете ее размер тем или иным образом, бухгалтерия, выполняемая в одной версии, будет пропущена из другой версии. Это упущение может привести к неожиданным результатам.

Внедрение Polyspace

Средство проверки помечает ситуации, когда некрупная версия operator delete существует, но соответствующая версия размера не определена, или наоборот.

Проверка включена только при указании версии C++ C + 14 или более поздней. ПосмотритеC++ standard version (-cpp-version).

Поиск неисправностей

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

Примеры

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

#include <new>
#include <cstdlib>

int global_store;

void update_bookkeeping(void *allocated_ptr, bool alloc) {
   if(alloc) 
      global_store++;
   else
      global_store--;
}

void operator delete(void *ptr);
void operator delete(void* ptr) {
    update_bookkeeping(ptr, false);
    free(ptr); 
}

void operator delete(void *ptr, std::size_t size);
void operator delete(void* ptr, std::size_t size) { 
    //Compliant, both sized and unsized version defined
    update_bookkeeping(ptr, false);
    free(ptr); 
}

void operator delete[](void *ptr);
void operator delete[](void* ptr) { //Noncompliant, only unsized version defined
    update_bookkeeping(ptr, false);
    free(ptr); 
}

В этом примере как невымеренная, так и размерная версия operator delete перегружены и соответствуют правилу. Однако только невымеренная версия operator delete[] перегружен, что нарушает правило..

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

Группа: Библиотека языковой поддержки
Категория: Обязательно, Автоматизировано
Представлен в R2019a