메인 콘텐츠로 건너뛰기
이 항목에서는 XBOX 개발을 위한 Microsoft Game Development Kit (GDK)에서 권장하는 다양한 Visual C++ 컴파일러 및 링커 스위치를 설명합니다.
Windows용 clang/LLVM의 경우 “MSVC와 유사한” clang-cl 프런트 엔드를 통해 동일한 스위치가 지원됩니다. clang 도구 집합에 대한 몇 가지 특정 스위치는 아래에 설명되어 있습니다.

C++ 언어 표준(/std)

Visual C++는 기본적으로 C++14 준수 모드입니다. C++17 준수 모드를 사용하려면 /std:c++17을 사용합니다. XBOX API용 Microsoft Game Development Kit (GDK)에는 C++11 이상이 필요하며, 타이틀 개발에는 C++14 이상의 사용이 완전히 지원됩니다.
/std:c++latest는 Visual Studio 2017 및 Visual Studio 2019에서 C++20 초안 준수를 사용하도록 설정합니다. /std:c++latest의 동작은 Visual C++ 서비스 업데이트에 따라 계속 변경되므로 주의해서 사용해야 합니다.
VS 2019(16.11) 및 VS 2022는 /std:c++20 스위치를 지원합니다. 이 블로그 게시물을 참조하세요.
VS 2019(16.8)부터 Visual C++ 컴파일러는 /std:c11 및 /std::c17을 지원합니다. 그러나 GameRuntime 및 기타 많은 GDK 헤더에는 C++11 이상이 필요합니다.
자세한 내용은 다음을 참조하세요.

일반 최적화에는 /O1 /Oi, “핫” 모듈에는 /O2 사용

XBOX One 및 XBOX Series X/S의 비순차 실행 CPU에서는 일반적으로 코드의 절대적으로 가장 빠른 버전보다 코드 세그먼트를 명령 캐시에 맞추는 것이 더 중요하므로 크기 최적화가 선호됩니다. 속도 최적화는 특정 모듈이나 함수에만 사용하세요. 내장 함수 생성은 부동 소수점 성능을 향상시키므로 게임에서는 추가 코드를 감수할 가치가 있습니다. 또한 특정 함수 또는 함수 집합을 #pragma optimize("t", on) / #pragma optimize("", on )으로 둘러싸서 해당 함수에 대해 속도 최적화를 사용하도록 설정할 수도 있습니다. 속도 최적화(/O2 또는 /Ox)는 공격적인 루프 언롤링으로 인해 프로그램 크기가 크게 증가할 수 있다는 점을 기억하세요.
SIMD(Single Instruction Multiple Data) 자동 벡터화 최적화는 /O2 또는 /Ox에서만 사용하도록 설정됩니다. PGO(프로필 기반 최적화)를 사용하면 속도 최적화와 크기 최적화를 정확히 어디에 적용할지 더 나은 선택을 할 수 있습니다.역사적인 이유로, /Ox는 O2와 거의 동일하지만 /GF(중복 문자열 제거)와 /Gy(함수 수준 링크 사용)가 모두 없다는 점에 유의해야 합니다. 따라서 일반적으로 /Ox보다 /O2를 사용하는 것이 좋습니다. /Ox를 사용하는 경우 링커 최적화를 사용하는 데 중요한 /Gy만큼은 반드시 명시적으로 사용하도록 설정하세요.

/fp:fast 컴파일러 스위치

Visual Studio 2005에서 도입된 /fp 플래그는 컴파일러에서 사용하는 다양한 부동 소수점 모델(fast, precise, strict, except)을 제어합니다. fast 부동 소수점 모델은 핵심 “C” 규칙에 속하지 않는 여러 최적화를 사용합니다. precise 부동 소수점 모델은 이러한 추가 최적화를 사용하지 않도록 설정하며 기본값입니다. 게임에는 /fp:fast를 사용하는 것이 좋습니다. 자세한 내용은 다음을 참조하세요. VS 2022에 새로 추가된 다음 부동 소수점 관련 플래그도 참조하세요.

/arch 컴파일러 스위치

x64 네이티브 플랫폼의 암시적 기본값은 /arch:SSE2입니다. XBOX One 본체(AMD Jaguar CPU)에서는 /arch:AVX를 사용해야 합니다. XBOX Series X/S(AMD Hercules CPU)에서는 /arch:AVX2를 사용하는 것이 좋습니다. /arch:AVX 또는 /arch:AVX2를 사용할 때의 주요 이점은 컴파일러가 원본 피연산자 중 하나를 결과로 덮어쓰는 표준 2-피연산자 인코딩 대신 비파괴적 3-피연산자 인코딩을 사용하는 VEX 접두사 버전의 SSE 명령을 생성한다는 것입니다. 이는 SSE 명령을 사용하는 x64 네이티브 코드의 스칼라 부동 소수점과 SSE 내장 함수의 명시적 사용 모두에 영향을 줍니다. 이를 통해 레지스터 스케줄링 부담을 줄이고 일부 movaps 명령을 제거할 수 있습니다. 자세한 내용은 다음을 참조하세요. Visual Studio 2019(16.3) 이상을 사용하는 XBOX Series X|S의 경우 vzeroupper 명령 사용에 대해 AMD Hercules CPU가 선호하는 동작에 맞게 최적화하도록 /d2vzeroupper도 사용해야 합니다. 전체 프로그램 최적화(/LTCG)의 경우 필요한 링커 해당 옵션은 /d2:-vzeroupper입니다. 이는 VS 2022 컴파일러의 기본 동작입니다. Visual Studio 2022를 사용하는 XBOX One의 경우 vzeroupper 명령 사용에 대해 AMD Jaguar CPU가 선호하는 동작에 맞게 최적화하도록 /d2vzeroupper-도 사용해야 합니다. 전체 프로그램 최적화(/LTCG)의 경우 필요한 링커 해당 옵션은 /d2:-vzeroupper-입니다. 이는 VS 2019 컴파일러의 기본 동작입니다.
clang/LLVM의 경우 XBOX One(AMD Jaguar CPU)에는 -march=btver2, XBOX Series X/S(AMD Hercules CPU)에는 -march=znver2를 사용합니다.
PC 개발의 경우 SSE 및 SSE2는 아키텍처 정의의 일부이므로 모든 x64 네이티브 CPU에서 지원된다고 가정할 수 있습니다. 또한 SSE3는 Windows 10 또는 Windows 11에서 지원하는 모든 최신 Intel CPU에서 지원되므로 안전하게 요구할 수 있습니다. PC에서 AVX 또는 AVX2처럼 SSE2를 넘어서는 기능을 사용하는 경우 반드시 런타임 CPU 지원 검사를 수행하세요.

/favor 컴파일러 스위치

/favor 스위치는 AMD64 프로세서와 Intel 64 프로세서에 대한 x64 컴파일러 최적화 선택을 제어합니다. XBOX 개발에는 /favor:AMD64를 사용합니다.

예외 처리 모델(/EHsc)

x64 네이티브 코드의 경우 예외 처리는 함수 에필로그나 프롤로그에 직접적인 코드 영향을 주지 않습니다. Windows x86은 모듈에 추가 코드를 삽입하는 스택 기반 체계를 사용했지만, x64 네이티브 코드 생성은 예외 처리 중에 스택을 올바르게 해제할 수 있도록 테이블 기반 체계를 사용합니다. x64 네이티브에서 사용하는 테이블 기반 체계는 스택 버퍼 오버런 공격의 대상이 되지 않으므로 보안성이 더 높다는 장점도 있습니다. 이 설계는 여러 가지 의미를 갖습니다.
  • 예외 처리는 생성된 코드의 명령 수에 영향을 주지 않습니다. Windows x86에서 사용하는 것과 같은 스택 기반 체계는 5~10%의 코드 페널티를 유발할 수 있지만, x64 네이티브 예외 처리는 실행 파일과 연결된 테이블 기반 데이터만 생성하며 추가 명령은 생성하지 않습니다. 권장하지 않지만 x64 네이티브에서 예외 처리를 명시적으로 사용하지 않도록 설정하더라도 C++ 처리를 위한 소량의 보조 데이터만 절약되며 스택 해제 데이터의 생성은 비활성화되지 않습니다.
  • try/catch 블록은 사용 비용이 저렴합니다. 스택 기반 체계에서 try/catch 블록은 추적을 위한 추가 코드를 더합니다. x64에서는 해제 테이블에 몇 개의 항목만 더 추가됩니다.
  • 예외 처리(즉, 실제로 예외를 throw하는 것)에는 몇 가지 추가 테이블 조회가 필요합니다. 스택 기반 체계는 예외를 더 빠르게 throw할 수 있지만 모든 코드 경로에서 페널티가 발생한다는 장단점이 있습니다. 테이블 기반 체계는 “throw”가 더 느리지만 다른 코드 경로에는 영향을 주지 않습니다. 예외는 일반적인 흐름 제어에 사용해서는 안 되며 실제로 예외적인 상황에서만 트리거되어야 하므로, 처리에 따른 이 추가 성능 비용은 전체 애플리케이션 성능에 비해 무시할 수 있는 수준입니다.
XBOX API용 Microsoft Game Development Kit (GDK)는 오류 결과를 반환할 때 예외 처리 대신 오류 코드 또는 HRESULT를 사용하므로, 타이틀 코드 베이스 내에서 C++ 예외 처리를 어느 정도 채택할지는 전적으로 사용자에게 달려 있습니다. 예외는 흐름 제어에 사용해서는 안 되므로, 일반적으로 가장 좋은 용도는 디버깅과 코딩을 단순화할 수 있는 “빠른 실패” 시나리오입니다. 표준 C++ 라이브러리의 상당 부분은 적절한 오류 처리를 위해 예외 처리가 사용하도록 설정되어 있다고 가정합니다. 예외 처리를 명시적으로 사용하지 않도록 설정하면 충돌 후 분석에 부정적인 영향을 주고 코드 생성도 개선되지 않으므로 권장하지 않습니다. /EHa는 최적화 프로그램을 방해할 수 있으므로 사용하지 않는 것이 좋습니다.
new 연산자는 할당에 실패하면 항상 C++ 예외를 throw합니다. throw하지 않는 버전의 new를 사용하려면 new (std::nothrow)를 사용해야 합니다. 자세한 내용은 std::nothrow(cppreference.com)를 참조하세요.
C++는 예외 처리를 명시적으로 사용하든 사용하지 않든 잘 작동하는 “예외 안전” 코드를 작성하기 위한 다양한 메커니즘을 제공합니다. 예를 들어 std::unique_ptr, std::shared_ptr, std::lock_guard가 있습니다. Microsoft::WRL::ComPtr와 같은 COM 스마트 포인터를 사용하여 COM 참조 횟수를 자동으로 처리하는 것은 “예외 안전”하며 오류가 발생할 가능성이 적습니다. 일반적으로 RAII(리소스 획득은 초기화) 코딩 패턴을 사용하는 것이 좋습니다.
기본적으로 VS 2019로 빌드된 x64 네이티브 코드는 개선된 예외 처리기 구현( __CxxFrameHandler4, __GSHandlerCheck_EH4)을 사용합니다. 따라서 VS 2019로 빌드된 정적 라이브러리는 VS 2017 C/C++ 런타임과 호환되지 않습니다. VS 2017로 빌드된 정적 라이브러리는 VS 2019와 호환됩니다.
자세한 내용은 다음을 참조하세요.

런타임 라이브러리(/MD, /MDd)

권장되는 선택은 Visual C/C++ 런타임의 다중 스레드 DLL 버전을 사용하는 것입니다. 이렇게 하면 코드 팽창이 최소화되고, DLL 간 상호 작용으로 인한 잠재적인 문제를 피할 수 있으며, 서비스가 간소화됩니다. 또한 모든 Microsoft 플랫폼에 권장되는 옵션입니다. XBOX용 Microsoft Game Development Kit (GDK)의 경우 이는 ucrt.lib 또는 ucrtd.lib에 연결하는 것을 의미합니다.
기술적으로는 libucrt.lib 또는 libucrtd.lib를 사용하여 /MT, /MTd를 통한 정적 CRT 연결을 사용할 수 있습니다. GDK에는 정적 CRT와 호환되는 확장 라이브러리가 포함되어 있지 않으므로 이 시나리오에 대한 지원은 제한적입니다.

호출 규칙(/Gd, /Gv)

x64용 네이티브 코드 생성은 처음 네 개의 매개 변수를 레지스터로 전달할 수 있는 단순한 표준 __fastcall 호출 규칙을 사용합니다.
  • 첫 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 RCX로 전달됩니다. float 또는 double인 경우 XMM0L로 전달됩니다. 그렇지 않으면 스택으로 전달됩니다.
  • 두 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 RDX로 전달됩니다. float 또는 double인 경우 XMM1L로 전달됩니다. 그렇지 않으면 스택으로 전달됩니다.
  • 세 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 R8로 전달됩니다. float 또는 double인 경우 XMM2L로 전달됩니다. 그렇지 않으면 스택으로 전달됩니다.
  • 네 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 R9로 전달됩니다. float 또는 double인 경우 XMM3L로 전달됩니다. 그렇지 않으면 스택으로 전달됩니다.
  • 다른 모든 매개 변수는 스택으로 전달됩니다.
  • 64비트에 맞는 반환 값은 RAX로 반환됩니다. XMM0은 float, double, __m128, __m128i, __m128d 값을 반환하는 데 사용됩니다. 그 외의 경우 호출자는 RCX의 0번째 인수로 메모리에 대한 포인터를 전달하며, RAX는 동일한 포인터와 함께 반환되어야 합니다.
이러한 점은 함수 시그니처가 짧을수록 성능이 더 좋고, 개체에 대한 포인터(또는 참조)를 전달하는 것이 값으로 전달하는 것보다 빠르다는 것을 의미합니다. 호출 규칙은 8바이트보다 큰 개체를 자동으로 참조로 전달합니다. __fastcall 체계에서는 SIMD 값이 레지스터로 전달되지 않습니다.
x64 네이티브 코드에서 __cdecl, __stdcall, __thiscall은 모두 __fastcall의 별칭입니다.
자세한 내용은 x64 호출 규칙(Microsoft Docs)을 참조하세요.

벡터 호출

Visual Studio는 x64 네이티브 코드 생성을 위해 __vectorcall이라는 선택적 호출 규칙을 지원합니다.
  • 첫 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 RCX로 전달됩니다. float, double, __m128, __m128i 또는 __m128d인 경우 매개 변수는 XMM0으로 전달됩니다. __m256, __m256i 또는 __m256d인 경우 YMM0으로 전달됩니다. 그렇지 않으면 첫 번째 매개 변수는 스택으로 전달됩니다.
  • 두 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 RDX로 전달됩니다. float, double, __m128, __m128i, __m128d, __m256, __m256i 또는 __m256d인 경우 매개 변수는 XMM1/YMM1로 전달됩니다. 그렇지 않으면 두 번째 매개 변수는 스택으로 전달됩니다.
  • 세 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 R8로 전달됩니다. float, double, __m128, __m128i, __m128d, __m256, __m256i 또는 __m256d인 경우 매개 변수는 XMM2/YMM2로 전달됩니다. 그렇지 않으면 세 번째 매개 변수는 스택으로 전달됩니다.
  • 네 번째 매개 변수가 정수 또는 포인터에 해당하는 경우 R9로 전달됩니다. float, double, __m128, __m128i, __m128d, __m256, __m256i 또는 __m256d인 경우 매개 변수는 XMM3/YMM3으로 전달됩니다. 그렇지 않으면 네 번째 매개 변수는 스택으로 전달됩니다.
  • 다섯 번째 매개 변수가 float, double, __m128, __m128i, __m128d, __m256, __m256i 또는 __m256d인 경우 매개 변수는 XMM4/YMM4로 전달됩니다. 그렇지 않으면 다섯 번째 매개 변수는 스택으로 전달됩니다.
  • 여섯 번째 매개 변수가 float, double, __m128, __m128i, __m128d, __m256, __m256i 또는 __m256d인 경우 매개 변수는 XMM5/YMM5로 전달됩니다. 그렇지 않으면 여섯 번째 매개 변수는 스택으로 전달됩니다.
  • 다른 모든 매개 변수는 스택으로 전달됩니다.
  • 64비트에 맞는 반환 값은 RAX로 반환됩니다. XMM0은 float, double, __m128, __m128i, __m128d 값을 반환하는 데 사용됩니다. YMM0은 __m256, __m256i 또는 __m256d 값을 반환하는 데 사용됩니다. 그 외의 경우 호출자는 RCX의 0번째 인수로 메모리에 대한 포인터를 전달하며, RAX는 동일한 포인터와 함께 반환되어야 합니다.
__vectorcall 규칙은 동일한 종류의 벡터 또는 부동 소수점 형식 하나 이상(최대 4개 멤버)으로 구성된 HVA(동종 벡터 집계) 형식도 처리할 수 있습니다(즉, struct * { __m128 v[4]; }는 HVA입니다). 값 매개 변수로서 HVA는 다른 매개 변수를 할당한 후 XMM0/YMM0 - XMM5/YMM5에 충분한 공간이 있으면 레지스터로 전달됩니다. 반환 값으로서 HVA는 XMM0/YMM0 - XMM3/YMM3을 통해 반환됩니다.
__vectorcall은 vararg 함수나 C++ 생성자를 지원하지 않습니다.
자세한 내용은 다음을 참조하세요.

전체 프로그램 최적화(/GL, /Gw, /LTCG)

기존 컴파일러 최적화 기법은 함수와 모듈을 최적화할 수 있지만, *링크 타임 코드 생성(LTCG)*이라고도 하는 전체 프로그램 최적화는 모듈 전체에 걸쳐 최적화를 수행합니다. 여기에는 부작용에 대한 더 나은 정보를 바탕으로 한 레지스터 할당 및 스케줄링 개선, 프로시저 간 상수/범위 전파, 부분 인라인 처리, 가능한 경우 개체에 대한 함수 호출의 가상화 해제가 포함됩니다.
LTCG는 증분 모드로도 사용하여 개발 반복 시 코드 성능 이점을 얻을 수 있습니다. 자세한 내용은 Speeding up the Incremental Developer Build Scenario(C++ 팀 블로그)를 참조하세요.
미리 빌드된 정적 C++ 라이브러리를 제공하는 미들웨어 공급업체의 경우 WPO를 사용하도록 설정하면 라이브러리가 컴파일러 도구 집합의 특정 릴리스에 종속됩니다. 이 시나리오에서는 WPO 없이 라이브러리를 제공해야 합니다. 이 조언은 DLL이나 소스에서 빌드된 코드에는 적용되지 않습니다.
자세한 내용은 /GL(전체 프로그램 최적화)(Microsoft Docs)을 참조하세요.
Visual Studio 2022(17.5)에는 /Gw와 관련된 새 준수 스위치 /Zc:checkGwOdr가 추가되었습니다. 이 블로그 게시물을 참조하세요.

프로필 기반 최적화

PGO(프로필 기반 최적화)는 LTCG 프로세스를 한 단계 더 발전시켜 애플리케이션의 이전 실행에서 수집한 성능 추적으로 전체 프로그램 최적화를 제어합니다. 이를 통해 기존 최적화의 품질이 향상될 뿐만 아니라, 작업 집합 및 분기 예측 개선을 위한 함수 레이아웃, 블록 레이아웃, 코드 분리 최적화도 향상됩니다. 자세한 내용은 프로필 기반 최적화(Microsoft Docs)를 참조하세요.

/OPT:REF,ICF 링커 스위치

이 스위치는 최종 실행 파일에 연결될 때 다양한 개체 모듈의 중복 콘텐츠를 제거합니다. 일반적으로 디버그 빌드에서는 사용하지 않지만 릴리스 빌드에서는 사용해야 합니다.
최상의 결과를 얻으려면 /Gy(함수 수준 링크 사용) 옵션을 사용하여 컴파일해야 합니다.

/GS 컴파일러 스위치

모든 코드의 릴리스 구성에서 버퍼 검사를 사용하는 것이 좋습니다. 보안 위협으로부터 안전한 특정 버퍼가 있지만 검사로 인해 성능이 영향을 받는 것으로 보이는 경우에는 /GS를 전역적으로 사용하지 않도록 설정하는 대신 함수에 __declspec(safebuffers)를 사용합니다. 위험도가 더 높은 코드에는 #pragma strict_gs_check(on)을 사용합니다. 자세한 내용은 /GS(버퍼 보안 검사)(Microsoft Docs)를 참조하세요.

/homeparams 컴파일러 스위치

최적화된 빌드에서 이 스위치를 사용하면 애플리케이션의 릴리스 빌드를 디버그하는 기능이 크게 향상될 수 있습니다. 프로덕션 빌드에 사용하면 크래시 덤프를 분석하고 디버그하는 프로세스를 단순화할 수 있습니다. 스택에 추가 매개 변수를 저장하기 위한 약간의 오버헤드가 추가됩니다. 대부분의 경우 성능에 눈에 띄는 영향을 주지 않습니다. 자세한 내용은 /homeparams(레지스터 매개 변수를 스택에 복사)(Microsoft Docs)를 참조하세요.

/Zc:inline 컴파일러 스위치

이 스위치는 인라인 함수 선언에 대해 더 엄격한 C++11 규칙을 적용하며, 모든 인라인 함수의 본문이 선언 및 사용과 동일한 컴파일 단위에 있어야 합니다. 이 플래그를 사용하면 빌드 시간이 향상되고 .obj 파일의 크기가 크게 줄어들 수 있습니다. 인라인 함수가 C++11을 준수하지 않으면 링크 시 LNK2019 오류가 발생합니다. 이 스위치는 MSBuild로 빌드할 때 기본적으로 켜져 있지만, 명령줄, CMake 등을 사용하여 빌드할 때는 명시적으로 추가해야 합니다. 자세한 내용은 /Zc:inline(참조되지 않은 COMDAT 제거)(Microsoft Docs)을 참조하세요.

/Zc:throwingNew 컴파일러 스위치

C++ 표준 및 표준 C++ 라이브러리 템플릿에서는 할당에 실패할 경우 new 연산자가 nullptr를 반환하는 대신 예외를 throw해야 합니다. new와 함께 std::nothrow를 사용하여 nullptr를 반환하는 동작을 강제할 수 있습니다. Visual C++ 컴파일러는 오랫동안 new를 호출할 때마다 null 검사를 생성해 왔는데, 이는 예외 처리가 있는 경우 불필요합니다. 이 스위치를 사용하면 추가 검사가 제거됩니다. 자세한 내용은 다음을 참조하세요.

/Zc:__cplusplus 컴파일러 스위치

역사적인 이유로 Visual C++의 __cplusplus 매크로는 오랫동안 “199711”을 반환해 왔습니다. Visual Studio 2017(15.7 업데이트)부터 이 새 스위치를 사용하면 Visual C++ 컴파일러가 올바른 표준 값을 반환합니다. 향후 버전의 컴파일러에서는 이것이 기본 동작이 되므로, 남아 있는 준수 문제를 해결하기 위해 가능한 한 빨리 이 스위치를 켜는 것이 좋습니다. 자세한 내용은 다음을 참조하세요.

/volatile:iso 컴파일러 스위치

volatile 키워드에는 Visual C++ 세대 간에도 실제로 이식 가능하지 않은, 동작과 관련된 여러 Microsoft 전용 확장 동작이 있습니다. 이 스위치를 켠 다음 코드에서 volatile을 잘못 사용하고 있지 않은지 확인하는 것이 좋습니다. 자세한 내용은 /volatile(volatile 키워드 해석)(Microsoft Docs)을 참조하세요.

/permissive- 컴파일러 스위치

Visual Studio 2017에서는 오래된 /Za 스위치를 대체하는 새 표준 준수 스위치가 도입되었습니다. 이 스위치를 사용하면 다른 컴파일러로 이식할 때 문제를 일으킬 수 있는 Microsoft 전용 확장 동작을 사용할 경우 컴파일러가 오류와 경고를 내보냅니다. /permissive-를 사용하면 컴파일 시간도 향상될 수 있습니다. 자세한 내용은 다음을 참조하세요.
Visual Studio 2017(15.3 업데이트)부터 /permissive-를 사용하면 2단계 이름 조회도 사용하도록 설정됩니다. 일부 C++ 템플릿 코드는 적절한 표준 적용 시 컴파일되지 않으므로, /permissive-를 완전히 사용하지 않도록 설정하는 대신 /Zc:twoPhase-를 사용하여 해당 부분만 선택적으로 사용하지 않도록 설정할 수 있습니다.자세한 내용은 다음을 참조하세요.
준수 적용과 관련된 추가 스위치로는 /Zc:lambda 및 /Zc:templateScope가 있습니다.

/Zc:preprocessor 컴파일러 스위치

Visual Studio 2019(16.6)에는 C99 준수 전처리기를 사용하도록 설정하는 새 스위치가 포함되어 있습니다. 이 스위치는 기본적으로 해제되어 있지만, 코드 이식성이 중요하다면 사용하도록 설정하는 것을 고려해야 합니다. Announcing full support for a C/C++ conformant preprocessor in MSVC를 참조하세요.

/ZH:SHA_256 컴파일러 스위치

디버깅 기호는 전통적으로 MD5 해싱을 사용해 왔습니다. 공급망 보안을 향상시키려면 대신 SHA-256을 사용하는 것이 좋습니다. Visual Studio 2022는 기본적으로 /ZH:SHA_256을 사용합니다.
이 스위치는 v16부터 clang/LLVM에서 지원됩니다.

/NXCOMPAT 및 /SAFESEH 링커 스위치

이 두 스위치는 x64 네이티브 대상을 사용할 때 암시적으로 적용됩니다. XBOX 타이틀에는 NX(실행 안 함) 보호가 필요하므로 /NXCOMPAT:NO를 사용할 수 없습니다.

/DYNAMICBASE 링커 스위치

이 스위치는 ASLR(주소 공간 레이아웃 임의 지정)을 사용하도록 설정하며 기본적으로 켜져 있습니다. 이는 XBOX 타이틀에 필요하므로 /DYNAMICBASE:NO를 사용할 수 없습니다. Visual Studio 2019(16.8) 이상에서는 링커의 성능이 크게 향상되어 더 이상 /Debug:FASTLINK 사용을 권장하지 않습니다. 로컬 빌드의 경우 이 링커 스위치를 사용하도록 설정하면 빌드 반복 시간이 크게 향상될 수 있습니다.
/Debug:FASTLINK를 사용하면 프로젝트의 기본 pdb에는 빌드 전체에 흩어져 있는 pdb 파일에 대한 링크만 포함된다는 점에 유의하세요. /Debug:FASTLINK 빌드의 기호를 공유하거나 저장하려는 경우 mspdbcmf.exe 명령줄 도구를 사용하여 전체 pdb 파일을 생성할 수 있습니다.자세한 내용은 다음을 참조하세요.

라이브러리

Gaming.Xbox.XboxOne.x64 및 Gaming.Xbox.Scarlett.x64 플랫폼의 경우 xgameplatform.lib에 연결하는 것이 중요합니다. 이는 본체에서 지원되는 모든 Win32 API를 포함하는 ‘포괄’ 라이브러리입니다. kernel32.lib, onecore.lib, onecoreuap.lib 또는 WindowsApps.lib와 연결하지 마세요. 포괄 라이브러리를 혼합하는 것은 권장되지 않으며 프로세스 시작 실패로 이어질 수 있습니다. ‘포괄’ 라이브러리에 대한 자세한 내용은 Microsoft Docs를 참조하세요.

/NODEFAULTLIB:library 링커 스위치

#pragma comment(lib,)를 통해 링크 시 지원되지 않는 라이브러리가 사용되지 않도록 일반적인 라이브러리 이름의 특정 목록과 함께 /NODEFAULTLIB 링커 스위치를 사용하는 것이 좋습니다.
라이브러리가 연결 입력으로 명시적으로 나열된 경우 /NODEFAULTLIB 라이브러리로 나열되어 있더라도 계속 사용됩니다. 이 스위치는 암시적 참조만 무시합니다.

Visual C++ 런타임 라이브러리

Visual Studio 개발자 명령 프롬프트는 이러한 경로를 찾는 데 필요한 환경 변수를 정의합니다. _Gaming.Xbox.*.x64_에서 Visual C++ 런타임 가져오기 라이브러리를 찾기 위한 올바른 /LIBPATH는 %VCToolsInstallDir%lib\onecore\x64입니다.

DLL(동적 연결 라이브러리)

_Gaming.Xbox.*.x64_용 Game OS에는 Visual C++ 런타임 DLL 라이브러리가 포함되어 있지 않습니다. 게임을 시작하려면 이러한 라이브러리를 타이틀 레이아웃에 포함해야 합니다.
  • 릴리스의 경우 %VCToolsRedistDir%onecore\x64\Microsoft.VC14?.CRT의 콘텐츠가 필요합니다. 동일한 레이아웃에 디버그 및 릴리스 바이너리가 혼합되어 있는 경우 모든 레이아웃에 이러한 콘텐츠를 포함해야 합니다.
  • 디버그의 경우 %VCToolsRedistDir%onecore\debug_nonredist\x64\Microsoft.VC14?.DebugCRT의 콘텐츠가 필요합니다.
  • 디버그의 경우 Windows SDK의 %WindowsSdkVerBinPath%x64\ucrt에 있는 디버그 버전의 ucrtbased.dll도 추가로 필요합니다. 릴리스 버전의 ucrtbase.dll은 Game OS에 포함되어 있습니다.
OpenMP를 사용하는 경우 Microsoft.VC14?.OpenMP 및/또는 Microsoft.VC14?.DebugOpenMP의 콘텐츠도 필요합니다.

참고 항목

CMakeExample 샘플
마지막 수정일 2026년 10월 6일