C++17 introduced Dynamic memory allocation for over-aligned data
Beside the existing std::max_align_t
, the fundamental alignment, it added __STDCPP_DEFAULT_NEW_ALIGNMENT__
the minimal alignment that the operator new guarantees.
With MSVC2017 64bit compilation, these constants result in a std::max_align_t
of size 8 and __STDCPP_DEFAULT_NEW_ALIGNMENT__
of size 16.
It is however allowed to overrule the operator new/free, as mentioned on cppreference: operator new - global replacements.
Looking at all of the documents, it's unclear to me if this function is allowed to provide a new default alignment and if so, if we are allowed to redefine this constant.
An example for illustration:
#include <new>
#include <iostream>
#include <cassert>
#include <cstdint>
#include <cstddef>
static_assert(alignof(std::max_align_t) == 8);
static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == 16);
void * operator new(size_t size)
{
std::cout << "New operator overloading " << std::endl;
void * p = std::malloc((size == 8) ? 16 : size);
assert(std::uintptr_t(p)%16 == 0);
if (size == 8)
{
auto correctedPtr = std::uintptr_t(p) + 8;
return (void*)correctedPtr;
}
return p;
}
void operator delete(void * p)
{
std::cout << "Delete operator overloading " << std::endl;
if (std::uintptr_t(p)%16 != 0)
{
auto correctedPtr = std::uintptr_t(p) - 8;
std::free((void*)correctedPtr);
}
std::free(p);
}
namespace
{
struct D
{
double d;
};
}
int main(int, char**)
{
new D{};
return 0;
}
The reason I'm asking this, is because I'm investigating crashes in an MSVC program that is now being compiled with Clang. Here we noticed that clang uses CPU instructions that rely on this 16 bit alignment in order to initialize a class of size 8.