Assert의 의미

목차

  1. Assert 컨디션이 헷갈리는 이유
  2. Assert는 언제 써야할까?
  3. Assert는 언제 쓰면 안될까?

현대 프로그래밍 패러다임에서 Assert를 사용하는 것은 중요하다. 프로그램이 특정 지점에서 조건이 참인지 확인하기 위한 목적으로 사용된다. 디버깅과 오류 검출을 용이하기 위한 것으로 Assert는 유저를 위한 것이 아닌 개발자를 위한 도구이다.

따라서 Assert의 모든 과정은 개발자 친화적으로 디자인되어야한다.(유저가 볼 일이 아니다. 유저를 위해 먼저 디버깅하는 용도니까. Only for dev!)

Assert는 개발/테스트 단계에서만 사용되고 릴리즈 버전에서서는 비활성화하여 컴파일한다.

여기가 중요하다

내가 공부를 하다 겪은 어려움은 다음과 같다

Assert(str != nullptr)

위의 코드는 str이 nullptr이라면 assert를 내고 메시지와 함께 강제 종료된다.

문제는 “조건식은 str != nullptr인데 왜 작동은 str == nullptr일까?”

라는 의문이 들었다.

굉장히 헷갈렸고 헷갈리니까 스스로 Assert를 사용할 때 오용할 가능성이 높을 것으로 느껴져, 의미적으로, 언어적으로 이해하려고 생각을 시작했다.

생각의 결과는 다음과 같았다.

assert라는 단어를 프로그래밍에서 사용하는 이유는 그 단어가 영어에서 가지는 본래의 의미 때문이다. 영어에서 assert는 “단언하다”, “주장하다” 또는 “확실히 말하다” 라는 의미를 가진다. 이 단어는 사실이나 주장을 강력하고 자신있게 표현할 때 사용된다. 프로그램밍에서 Assert 구문은 이러한 언어적 의미를 반영한다. 코드 내에서 assert를 사용할 때, 개발자는 프로그래밍의 특정 지점에서 특정 조건이 반드시 참이어야 한다고 "단언"하는 것이다. 즉, 개발자는 그 조건이 참이라는 것을 강력하게 주장하며, 그 주장이 거짓일 경우 프로그램에 오류가 있음을 나타내며 프로그램이 종료된다.

assert의 뜻이 “주장하다”, “단언하다”라서 만약 Assert(str != nullptr)라고 작성하면 개발자는 str != nullptr이라고 강력히 주장하는 느낌이다.

개발자가 그렇게까지 단언하고 str != nullptr이라고 주장하고 있는데 만약 str == nullptr이 들어오면 프로그램은 “네 주장이랑 다른데? 종료할게”하고 강제종료 시키는 것이다.

다시 예를 들어, assert(x > 0)라는 코드는 “x는 0보다 커야 한다”라는 조건을 단언하는 것이다. 만약 이 조건이 만족되지 않으면, 즉 x가 0 이하이면, 프로그램은 개발자의 주장과 다른 상태임을 나타내며 중단된다.

이처럼 assert는 프로그램이 예상대로 작동하는지 확인하기 위한 강력한 도구로서, 개발자의 의도와 프로그램의 실제 동작 사이에 불일치가 있을 때 이를 식별하는 데 사용된다.

이 단어(assert)의 선택은 프로그래밍에서의 기능과 언어적 의미가 잘 부합하는 예시이다.

주장하다 라는 뜻을 이미 알고 있었지만 헷갈렸던 이유는 ‘개발자’가 주장하는 것인지 ‘프로그램’이 주장하는 것인지에 대한 혼란 때문이었던 것 같다. ‘개발자’가 주장하는 것임을 기억한다면 코딩이 매우 쉬워진다.

그러면 언제 Assert를 사용해야하는 것일까?

  1. pre-condition과 post-condition을 확인 하는 용도
method(obj)
{
	// pre-condition assert.
	// 아래의 로직에 진입해도 문제 없는 값인지 확인
	Assert(obj == x) 

	// [로직]
	// obj의 값이 변하는 구간
	something(obj)
	setSetSet(obj)
	...

	// post-condition assert.
	// 로직 이후의 obj 값이 정상적인지 확인
	Assert(obj == y)

}
  1. 어떤 아키텍트에 의하면 7줄마다 assert가 들어가는 것이 바람직하다고 한다.
  2. 문제가 생겼을 때 exception을 throw하는 처리는 호출한 함수에게 책임을 전가하는 것. 가급적 Assert로 해결하는 것이 좋다.

그러면 잘못된 Assert는 무엇일까?

method(obj)
{

	Assert(obj.IsValid())
	if (!obj.IsValid())
		return false

	// 로직
	...
}

우선 Assert가 가지는 explicit(명시적, 절대적인)함를 이해해야한다.

위의 코드가 잘못된 점은 다음과 같다.

obj가 valid한지 검사하여 valid하지 않다면 false를 리턴하고 있다.

문제는 그 전에 valid한지 assert로 체크하고 있다는 것이다.

이 Assert가 가지는 의미는 해당 obj가 valid하지 않다면 해당 함수는 절대로 호출되지 않을 것이라고 단언하는 것이지만 함수 내에서 유효성을 검사하고 있다는 것이다.

다시말해 Assert를 썼다면 Assert에 걸릴만한 조건이 들어오지 않도록 코드를 작성해야 한다.

Categories:

Updated:

Leave a comment