기존의 C++에 존재하는 assertion을 발생하는 키워드는 #error 전처리기와 assert 메크로를 통해 발생시킬 수 있습니다.
Assert
동적으로 배열을 할당 할 때 배열 사이즈는 양수이여야 하기 때문에 이를 assert를 통해서 검증할 수 있습니다.
#include <iostream>
#include <cassert>
using namespace std;
void foo (int age)
{
// assert를 이용한 유효성 확인
assert(age > 50);
int* p = new int[age];
}
int main(int argc, char* argv[])
{
foo(26);
return 0;
}
위와 같이 assert를 이용한다면 오류가 발생하면 개발자에게 프로그램이 다양한 정보(Call Stack, 발생 위치 등)를 알려주어 유효성을 쉽게 검증 할 수 있도록 도와준다.
error
#if !defined(__cplusplus)
#error C++ compiler required.
#endif
전처리기가 전처리 지시자인 #error를 만나면 컴파일 오류를 발생시키며 뒤에 나오는 C++ compiler required 라는 문자열을 화면에 출력합니다.
단점
위의 assertion을 발생시키는 assert메크로와 #error 전처리 지시자는 단점이 존재합니다.
assert의 경우 런타임에 비교를 수행하기에 성능의 하락을 불러올 수 있다는 점과
#error의 경우 컴파일 시간에 처리가 가능하나 템플릿이 구체화 되기 전에 수행되므로 C++에서는 적절하지 않습니다.
#error가 왜 적절하지 않냐면 C++ 빌드 process를 간단한게 생각해보면
1. 전처리 : 문자해석, 전처리 토큰 분리, 전처리 실행 ... etc...
2. 컴파일 : 해석 유닛 생성(TU), 인스턴스 유닛 생성(IU) -> 이곳에서 TU를 분석해서 필요로 하는 템플릿 인스턴스들을 확인합니다. 템플릿들의 정의 위치가 확인이 되면 해당 템플릿들의 인스턴스화가 진행됩니다.
3. 링킹 => 목적파일
4. 실행파일
c++빌드과정이 위와 같기 때문에 #error를 템플릿과 쓸 수가 없습니다.
static_assert
위의 문제들때문에 c++11에 static_assert가 등장하였습니다.
이는 컴파일 타임에 소프트웨어 assertion을 위해서 추가된 문법입니다.
작성된 상수 표현식이 false인 경우 컴파일러는 메세지를 출력하고 C2338에러를 출력합니다. true인경우 아무것도 하지 않습니다.
static_assert( constant-expression, string-literal );
static_assert( constant-expression ); // Visual Studio 2017 and later
UE의 PawnComponent의 GetPawnChecked라는 함수가 있는데 GetOwner호출한뒤 CastChecked로 캐스팅하여 확인후 반환하는 함수입니다.
template <class T>
T* GetPawnChecked() const
{
static_assert(TPointerIsConvertibleFromTo<T, APawn>::Value, "'T' template parameter to GetPawnChecked must be derived from APawn");
return CastChecked<T>(GetOwner());
}
상수 표현식은 "TPointerIsConvertibleFromTo<T, APawn>::Value"가 되며 이는 Tests if a From* is convertible to a To* 를 확인합니다. 여기서 Value는 bool값입니다.
따라서 ::Value가 false라면 뒤의 문자열을 출력하고 true라면 아무것도 하지 않습니다.
https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/Templates/TPointerIsConvertibleFromTo/
https://dydtjr1128.github.io/cpp/2019/06/03/Cpp-static_assert.html
'UE5' 카테고리의 다른 글
[UE] Lyra ExperienceManagerComponent::StartExperienceLoad (1) | 2024.01.25 |
---|---|
[UE] Unreal Smart Pointer (0) | 2024.01.23 |
[UE] C1189 에러 해결방법 (0) | 2024.01.22 |
[UE] IsA (0) | 2024.01.20 |
[UE] UObject::CreateUObject Delegate 바인딩 언제, 어디서, 왜 쓰는지 (0) | 2024.01.05 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!