개발일지/소프트 렌더러

소프트웨어 렌더러 만들기 - 5 (Custom Assertion)

hwi.middle 2023. 11. 11. 02:47

여기까지의 작업내용: https://github.com/hwi-middle/HimchanSoftwareRenderer/tree/f069823fcd73b59876f2b7fddf085b1d647bf826

 

GitHub - hwi-middle/HimchanSoftwareRenderer: C++로 구현한 소프트웨어 렌더러입니다.

C++로 구현한 소프트웨어 렌더러입니다. Contribute to hwi-middle/HimchanSoftwareRenderer development by creating an account on GitHub.

github.com

Assertion 매크로

#pragma once

#ifdef NDEBUG

#define ASSERT(expression) ((void)0)

#else
#include <fstream>
#include <iostream>
#include <sstream>

#define ASSERT(expression) do {                                                 \
    if (!(expression)) {                                                        \
		std::ostringstream messageStream;                                       \
		messageStream << "Assertion failed: " << #expression << "\n";	        \
        messageStream << "at [" << __FILE__ << "] (" << __func__ << ")\n";      \
        messageStream << "line " << __LINE__ << "\n";                           \
		std::ofstream outfile("Error.log");                                     \
		std::cerr.rdbuf(outfile.rdbuf());                                       \
        std::cerr << messageStream.str();                                       \
        std::cout << messageStream.str();                                       \
        std::cout << "The log file has been saved as 'Error.log'";              \
        __debugbreak();                                                         \
    }                                                                           \
} while (0)

#endif

__debugbreak를 통해서 런타임 assertion을 구현했다. 다만 문제가 있었는데, constexpr 함수에서는 이 매크로를 사용할 수 없었다. 내가 만든 ASSERT 매크로는 런타임 assertion인데 constexpr 함수의 내부에서는 컴파일 타임에 값을 결정해야하기 때문이다.

 

C 표준의 assert 매크로는 constexpr 함수에서도 사용할 수 있어서 별 생각없이 나도 런타임 assertion 매크로를 구현했는데, 애초에 C 표준 assert 매크로도 C++ 14까지는 constexpr 함수에서 사용할 수 없었다가 C++ 17에 들어서 가능하게 바뀌었다고 한다. constexpr 함수의 규칙에 일종의 예외를 둔 것이다.

 

내가 만든 매크로는 이러한 예외가 될 수 없으므로 constexpr 함수에서 사용할 수 없다. 그렇다면 선택지는 간단하다. 그냥 얌전히 C 표준의 assert매크로를 쓰거나, constexpr에서만 내가 만든 ASSERT를 피해가거나, constexpr 함수를 쓰지말거나...

 

고르자면 그냥 C 표준의 assert 매크로를 쓰는게 나을 것 같다.

 

아쉽지만 공부한 셈 치고 넘어가도록 하자.