Поделиться через


/Zc:alignedNew (выделение на C++17 с превышением выравнивания)

Включите поддержку выравнивания C++17new, динамическое выделение памяти, выровненное по границам больше, чем значение по умолчанию для стандартного выровненного типа. max_align_t

Синтаксис

/Zc:alignedNew[-]

Замечания

Поддержка компилятором и библиотекой MSVC стандартного выделения памяти с избыточным выравниванием C++17. /Zc:alignedNew При указании параметра динамическое выделение, напримерnew Example;, учитывает выравнивание Example даже в том случае, если оно большеmax_align_t, наибольшее выравнивание, необходимое для любого фундаментального типа. Если выравнивание выделенного типа не превышает выравнивание, гарантированное исходным оператором, доступно в качестве значения предопределенного макросаnew__STDCPP_DEFAULT_NEW_ALIGNMENT__, оператор new Example; приводит к ::operator new(size_t) вызову, как и в C++14. Если выравнивание больше __STDCPP_DEFAULT_NEW_ALIGNMENT__, реализация получает память с помощью ::operator new(size_t, align_val_t). Аналогичным образом удаление типов с избыточным выравниванием вызывает ::operator delete(void*, align_val_t) или сигнатуру удаления ::operator delete(void*, size_t, align_val_t) с определенным размером.

Этот /Zc:alignedNew параметр доступен только в том случае, если /std:c++17 включена или более поздняя версия. В /std:c++17 разделе или более поздних /Zc:alignedNew версиях по умолчанию включен стандарт C++. Если единственной причиной реализации оператора new и delete является поддержка чрезмерно выровненных выделений, возможно, вам больше не потребуется этот код в режимах C++17 или более поздних версий. Чтобы отключить этот параметр и вернуться к поведению new C++14 и delete при использовании /std::c++17 или более поздней версии, укажите /Zc:alignedNew-. Если вы реализуете оператор, но delete вы не готовы реализовать слишком выровненный оператор new new и delete перегрузки с align_val_t параметром, используйте /Zc:alignedNew- параметр, чтобы предотвратить создание вызовов к пересоединяемым перегрузкам компилятора и стандартной библиотеки. Параметр /permissive- не изменяет параметр /Zc:alignedNewпо умолчанию.

/Zc:alignedNew Поддержка доступна начиная с Visual Studio 2017 версии 15.5.

Пример

В этом примере показано, как работает оператор и оператор new delete при /Zc:alignedNew установке параметра.

// alignedNew.cpp
// Compile by using: cl /EHsc /std:c++17 /W4 alignedNew.cpp
#include <iostream>
#include <malloc.h>
#include <new>

// "old" unaligned overloads
void* operator new(std::size_t size) {
    auto ptr = malloc(size);
    std::cout << "unaligned new(" << size << ") = " << ptr << '\n';
    return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size) {
    std::cout << "unaligned sized delete(" << ptr << ", " << size << ")\n";
    free(ptr);
}

void operator delete(void* ptr) {
    std::cout << "unaligned unsized delete(" << ptr << ")\n";
    free(ptr);
}

// "new" over-aligned overloads
void* operator new(std::size_t size, std::align_val_t align) {
    auto ptr = _aligned_malloc(size, static_cast<std::size_t>(align));
    std::cout << "aligned new(" << size << ", " <<
        static_cast<std::size_t>(align) << ") = " << ptr << '\n';
    return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size, std::align_val_t align) {
    std::cout << "aligned sized delete(" << ptr << ", " << size <<
        ", " << static_cast<std::size_t>(align) << ")\n";
    _aligned_free(ptr);
}

void operator delete(void* ptr, std::align_val_t align) {
    std::cout << "aligned unsized delete(" << ptr <<
        ", " << static_cast<std::size_t>(align) << ")\n";
    _aligned_free(ptr);
}

struct alignas(256) OverAligned {}; // warning C4324, structure is padded

int main() {
    delete new int;
    delete new OverAligned;
}

Такой результат является типичным для 32-разрядных сборок. Значения указателя могут варьироваться в зависимости от того, где приложение выполняется в памяти.

unaligned new(4) = 009FD0D0
unaligned sized delete(009FD0D0, 4)
aligned new(256, 256) = 009FE800
aligned sized delete(009FE800, 256, 256)

Сведения о вопросах соответствия в Visual C++ см. в статье Nonstandard Behavior.

Установка данного параметра компилятора в среде разработки Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.

  3. Измените свойство "Дополнительные параметры", чтобы включить /Zc:alignedNew или /Zc:alignedNew- нажмите кнопку "ОК".

См. также

/Zc (соответствие)