본문 바로가기
Unreal Engine 5

UE5 언리얼 엔진에서 Asset란? check와 ensure의 차이점

by 니키티스 2024. 7. 13.

해당 문서는 언리얼 엔진의 공식 문서 "언리얼 엔진의 어서트 | 언리얼 엔진 5.4 문서 | Epic Developer Community (epicgames.com)"를 읽고 제가 이해한 바를 조금 덧붙여서 정리한 글입니다. 오류가 있다면 지적해주시면 감사하겠습니다.


프로그래밍을 할 때 반드시 null이 아니어야 한다던가, 이런 걸 개발 과정에서 테스트할 땐 Assert 문을 많이 사용한다. Log처럼 알림을 띄울 뿐만 아니라 아예 동작을 멈춰버리게 해서 오류를 강력하게 알려주기 때문이다.

언리얼 엔진에서 무언가를 검증할 땐 check와 ensure 같은 Assert 매크로를 사용한다.

언리얼 엔진에서 제공하는 Assert 매크로는 종류가 다양한데, check, verify, checkf, ensure 등 종류가 다양하다.

 

이를 간단하게 정리하면,

(1) check, verify 외 일반 Assert 시리즈: 실패하면 아예 실행을 중단해버린다.

(2) checkSlow, verifySlow 시리즈: 1과 같은데 디버그 빌드용

(3) ensure 시리즈: 실패해도 실행은 계속된다. 대신 도움이 되는 콜스택을 띄운다.

이렇게 정리할 수 있다. 이에 대해 좀 더 자세히 살펴보자.

Assert (1): 표현식이 안 맞으면 실행 중단

이 파트는 표현식이 false면 아예 실행을 중단해버린다. 그런 점에서 강력한 편이다.

대부분 DO_CHECK를 확인한다.

  • check(표현식): 표현식이 false이면 실행 중단.
    • 단, DO_CHECK = 1일 때만, 즉 매크로가 빌드 과정에서 컴파일될 때만 실행된다. 
check(Mesh != nullptr);
check(bWasInitialized && "Did you forget to call Init()?");
  • verify(표현식): check와 똑같은데, DO_CHECK가 꺼져 있어도 실행을 중단한다. 플레이 중 변수 할당이 제대로 이뤄졌는지 확인하기 좋다.
verify((Mesh = GetRenderMesh()) != nullptr);
  • checkf(표현식, …): 표현식이 true가 아니면 디버깅에 도움이 되는 정보(디버그 메시지)를 제공하면서 실행을 중단한다. check처럼 컴파일할 때만 실행됨.
checkf(WasDestroyed, TEXT( "Failed to destroy Actor %s (%s)"), *Actor->GetClass()->GetName(), *Actor->GetActorLabel());
checkf( TCString<ANSICHAR>::Strlen( Key ) >= KEYLENGTH( AES_KEYBITS ), TEXT( "AES_KEY needs to be at least %d characters" ), KEYLENGTH( AES_KEYBITS ) );
  • verifyf(표현식, …): checkf와 유사하지만, verify처럼 언제나 실행된다.
  • checkCode(표현식): check보다 좀 더 복잡함. 한 번 실행되는 do/while 루프 안에서 표현식을 실행한다.
    • 실제 구현은 다음과 같다. 엔진에서 잘 사용하지는 않고, DO_CHECK가 꺼져 있으면 컴파일에서 제외됨.
    • 코드를 한 번 실행해서 확인한다는 목적이라 보면 되겠다.
#ifndef checkCode
	#define checkCode( Code )		do { Code; } while ( false );
  • checkNoEntry(): 표현식이 없다. 절대 실행될 일 없는 곳에다가 넣는다.
switch (MyEnum)
{
    case MyEnumValue:
        break;
    default:
        checkNoEntry();
        break;
}
  • checkNoReentry(): 호출하고 있는 함수에 다시 진입하는 경우를 막는다.
    • 로딩을 하고 있는데 다시 로딩 함수를 호출하는 것을 막는 경우가 대표적일 것 같다.
    • 실제 구현은 이렇다. 해당 블록을 실행하는데 또 하는 경우를 막는다.
#ifndef checkNoReentry
	#define checkNoReentry()     { static bool s_beenHere##__LINE__ = false;                                         \
	                               check( !"Enclosing block was called more than once" || !s_beenHere##__LINE__ );   \
								   s_beenHere##__LINE__ = true; }
#endif
  • checkNoRecursion(): checkNoReentry()와 동일하다. 이름을 명시해서 재귀를 막을 목적임을 알리는 용도이다.
  • unimplemented(): 함수에 구현이 없어서 특정 클래스에서 호출하면 안되거나 덮어써야 하는 함수를 표시할 때 사용한다.
    • 함수를 구현하긴 해야 하는데 내용은 없고, 자식 클래스에서 덮어씌울 때 사용한다고 보면 되겠다.
class FNoImpl
{
	virtual void DoStuff()
	{
		// You must override this
		unimplemented();
	}
};

 

Assert (2): 디버그 빌드에서만 확인

디버그 빌드에서만 확인하는 용도이다. 그래서 DO_CHECK 말고 DO_GUARD_SLOW를 확인한다는 특징이 있다.

  • checkSlow(), checkfSlow(), verifySlow(): check, checkf, verify와 같지만 DO_CHECK가 아니라 DO_GUARD_SLOW가 켜졌을 때만 실행된다.

DO_GUARD_SLOW는 보통 디버그 빌드에만 켠다(프로젝트에서 직접 바꿀 수 있긴 하다).

위 코드는 느리면서 규칙을 꼼꼼하게 따질 것으로 보이는 코드에 넣는다고 가정한다.

그래서 DO_GUARD_SLOW는 Development나 Shipping 빌드에서는 굳이 안 쓰고 디버그 빌드에서만 켜진다.

Assert (3): 실행은 중단시키지 않지만 콜스택을 생성

세 번째 부류는 표현식이 실패(false)한다고 해서 아예 프로그램을 중단하진 않는다. 대신 그에 대한 콜스택을 만들어준다. 이름은 ensure로 시작한다.

이 매크로 표현식은 항상 실행되며 조건 식 안에도 넣을 수 있어서 특이하다.

(1) 종류처럼, DO_CHECK로 켤 수 있다.

  • ensure(표현식): 표현식을 검증해서 실패하면 그 지점까지 이르는 콜스택을 생성한다.
    • 특이한 것이, 아래 예시를 보면 아예 if문에 조건으로 넣을 수 있다. 조건문과 역할은 같은데, 실패시 콜스택을 생성해주는 추가 기능이 있다고 이해할 수 있다.
if (ensure( InObject != NULL ))
{
	InObject->Modify();
}
  • ensureMsg(표현식, 메시지): 표현식을 검증하는 건 ensure와 같은데, 실패하면 메시지를 포함해서 콜스택을 생성해준다.
    • 콜스택 메시지 버전이라 볼 수 있다.
ensureMsg(Node != nullptr, TEXT("Node is invalid"));
  • ensureMsgf(표현식, 메시지, …): 이것도 표현식을 검증하는 건 ensure와 같은데, 콜스텍에 메시지와 상세 정보를 포함한다.
    • 예시를 보면, 추적하고 싶은 변수 같은 걸 넣는 식이다. 아래 코드를 보면, 세 번째 인자로 int32(bModal)을 넣어서 이 변수의 값을 추적한다.
if (ensureMsgf(!bModal, TEXT("Could not create dialog because modal is set to (%d)"), int32(bModal)))
{
	...
}

 

참고

언리얼 엔진의 어서트 | 언리얼 엔진 5.4 문서 | Epic Developer Community (epicgames.com)

'Unreal Engine 5' 카테고리의 다른 글

GetWorld와 GetLevel은 어떻게 구현되어 있을까?  (0) 2024.04.25

댓글