/Zc:alignedNew
(alocação com excesso de alinhamento do C++17)
Habilite o suporte para alocação de memória dinâmica do operador new
com excesso de alinhamento do C++17 alinhada em limites maiores que o padrão para o tipo alinhado padrão de tamanho máximo, max_align_t
.
Sintaxe
/Zc:alignedNew
[-
]
Comentários
O compilador MSVC e a biblioteca são compatíveis com alocação de memória dinâmica padrão com excesso de alinhamento C++17. Quando a opção /Zc:alignedNew
for especificada, uma alocação dinâmica, como new Example;
, respeitará o alinhamento de Example
mesmo quando ele for maior do que max_align_t
, o maior alinhamento necessário para qualquer tipo fundamental. Quando o alinhamento do tipo alocado não for mais do que o alinhamento garantido pelo operador original new
, disponível como o valor da macro predefinida __STDCPP_DEFAULT_NEW_ALIGNMENT__
, a instrução new Example;
resultará em uma chamada para ::operator new(size_t)
como acontecia no C++14. Quando o alinhamento for maior que __STDCPP_DEFAULT_NEW_ALIGNMENT__
, a implementação obterá a memória usando ::operator new(size_t, align_val_t)
. Da mesma forma, a exclusão de tipos com excesso de alinhamento invoca ::operator delete(void*, align_val_t)
ou a assinatura de exclusão dimensionada ::operator delete(void*, size_t, align_val_t)
.
A opção /Zc:alignedNew
só está disponível quando /std:c++17
ou posterior está habilitada. No /std:c++17
ou posterior, /Zc:alignedNew
é habilitada por padrão para conformidade com o padrão do C++. Se o único motivo para implementar os operadores new
and delete
for dar suporte a alocações com excesso de alinhamento, você poderá não precisar mais desse código no C++17 ou nos modos posteriores. Desative essa opção e reverta para o comportamento do C++14 de new
e delete
; quando você usa /std::c++17
ou posterior, especifique /Zc:alignedNew-
. Se você implementar os operadores new
e delete
, mas não estiver pronto para implementar as sobrecargas dos operadores new
e delete
com excesso de alinhamento e que têm o parâmetro align_val_t
, use a opção /Zc:alignedNew-
para impedir que o compilador e a Biblioteca Padrão gerem chamadas para as sobrecargas com alinhamento excessivo. A opção /permissive-
não altera a configuração padrão de /Zc:alignedNew
.
O suporte ao /Zc:alignedNew
está disponível a partir do Visual Studio 2017 versão 15.5.
Exemplo
Nesta amostra, é possível ver como os operadores new
e delete
se comportam quando a opção /Zc:alignedNew
está definida.
// 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;
}
Esta saída é comum para builds de 32 bits. Os valores do ponteiro variam de acordo com o local no qual seu aplicativo é executado na memória.
unaligned new(4) = 009FD0D0
unaligned sized delete(009FD0D0, 4)
aligned new(256, 256) = 009FE800
aligned sized delete(009FE800, 256, 256)
Para obter mais informações sobre problemas de conformidade no Visual C++, consulte Comportamento não padrão.
Para definir esta opção do compilador no ambiente de desenvolvimento do Visual Studio
Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.
Selecione a página de propriedades Propriedades de Configuração>C/C++>Linha de Comando.
Modifique a propriedade Opções Adicionais para incluir
/Zc:alignedNew
ou/Zc:alignedNew-
, e escolha OK.