Main Content

AUTOSAR C++14 Rule A18-5-4

If a project has sized or unsized version of operator 'delete' globally defined, then both sized and unsized versions shall be defined

Description

Rule Definition

If a project has sized or unsized version of operator 'delete' globally defined, then both sized and unsized versions shall be defined.

Rationale

The C++14 Standard defines a sized version of operator delete. For instance, for an unsized operator delete with this signature:

void operator delete (void* ptr);
The sized version has an additional size argument:
void operator delete (void* ptr, std::size_t size);
See the C++ reference page for operator delete.

The Standard states that if both versions of operator delete exist, the sized version must be called because it provides a more efficient way to deallocate memory. However, in some cases, for instance to delete incomplete types, the unsized version is used.

If you overload the unsized version of operator delete, you must also overload the sized version. You typically overload operator delete to perform some bookkeeping in addition to deallocating memory on the free store. If you overload the unsized version but not the sized one or the other way around, any bookkeeping you perform in one version will be omitted from the other version. This omission can lead to unexpected results.

Polyspace Implementation

The checker flags situations where an unsized version of operator delete exists but the corresponding sized version is not defined, or vice versa.

The checker is enabled only if you specify a C++ version of C++14 or later. See C++ standard version (-cpp-version).

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#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); 
}

In this example, both the unsized and sized version of operator delete are overloaded and complies with the rule. However, only the unsized version of operator delete[] is overloaded, which violates the rule..

Check Information

Group: Language Support Library
Category: Required, Automated

Version History

Introduced in R2019a