다음을 통해 공유


/Zc:alignedNew (C++17 과도하게 정렬된 할당)

최대 크기의 표준 맞춤 new형식 max_align_t에 대한 기본값보다 큰 경계에 정렬된 C++17 오버 정렬 동적 메모리 할당에 대한 지원을 사용하도록 설정합니다.

구문

/Zc:alignedNew[-]

설명

MSVC 컴파일러 및 라이브러리는 C++ 17 표준 과다 정렬된 동적 메모리 할당을 지원합니다. /Zc:alignedNew 옵션을 지정하면 동적 할당(예: new Example; 기본 형식에 필요한 가장 큰 맞춤)보다 max_align_t큰 경우에도 맞춤 Example 이 적용됩니다. 할당된 형식의 맞춤이 미리 정의된 매크로__STDCPP_DEFAULT_NEW_ALIGNMENT__의 값으로 사용할 수 있는 원래 연산new자가 보장하는 맞춤보다 작으면 문 new Example; 은 C++14에서와 같이 호출 ::operator new(size_t) 됩니다. 맞춤이 보다 __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 이상 모드에서 이 코드가 더 이상 필요하지 않을 수 있습니다. 이 옵션을 해제하고 C++14 동작 new delete 으로 되돌리려면 사용하거나 나중에 사용할 /std::c++17 때를 지정합니다 /Zc:alignedNew-. 연산자를 new delete 구현하지만 매개 변수가 있는 오버 정렬된 연산 new 자 및 delete 오버로드를 align_val_t 구현할 준비가 되지 않은 경우 이 옵션을 사용하여 /Zc:alignedNew- 컴파일러 및 표준 라이브러리가 과도하게 정렬된 오버로드에 대한 호출을 생성하지 못하도록 합니다. 이 /permissive- 옵션은 .의 /Zc:alignedNew기본 설정을 변경하지 않습니다.

/Zc:alignedNew 지원은 Visual Studio 2017 버전 15.5부터 사용할 수 있습니다.

예시

이 샘플에서는 옵션이 설정되면 연산자와 연 newdelete 자가 /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. 프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 Visual Studio에서 C++ 컴파일러 및 빌드 속성 설정을 참조하세요.

  2. 구성 속성>C/C++>명령줄 속성 페이지를 선택합니다.

  3. 추가 옵션 속성을 수정하여 포함 /Zc:alignedNew 하거나 /Zc:alignedNew- 선택한 다음 확인을 선택합니다.

참고 항목

/Zc(규칙)