

가장 과도하게 엔지니어링 된 C ++ Assertion Library
도서관 철학 : 가능한 한 많은 유용한 진단 정보를 제공하십시오.
도서관이하는 멋진 일들 중 일부는 다음과 같습니다.
void zoog ( const std::map<std::string, int >& map) {
DEBUG_ASSERT (map. contains ( " foo " ), " expected key not found " , map);
}
ASSERT (vec.size() > min_items(), "vector doesn't have enough items", vec);
std::optional< float > get_param ();
float f = * ASSERT_VAL (get_param());
어설 션 유형 :
조건부 어설 션 :
DEBUG_ASSERT : 디버그에서 확인했지만 릴리스에는 아무것도 수행하지 않습니다 (표준 라이브러리의 assert 과 유사)ASSERT : 디버그와 릴리스를 모두 체크했습니다ASSUME : 디버그에서 확인하고 릴리스에서 최적화 힌트 역할을합니다.무조건적인 주장 :
PANIC : 디버그와 릴리스에서 트리거합니다UNREACHABLE : 디버그 트리거, 릴리스에서 도달 할 수없는 것으로 표시 Lowecase assert 선호합니까?
소문자 debug_assert 활성화하고 -DLIBASSERT_LOWERCASE 사용하여 별칭을 assert 할 수 있습니다.
기능 요약 :
ASSERT_EQ 등과 같은 매크로가없는 어설 션 표현의 자동 분해DEBUG_ASSERT_VAL 및 ASSERT_VAL 변형 값을 반환하여 코드에 원활하게 통합 될 수 있도록 값을 FILE* f = ASSERT_VAL(fopen(path, "r") != nullptr) . include (FetchContent)
FetchContent_Declare(
libassert
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git
GIT_TAG v2.1.2 # <HASH or TAG>
)
FetchContent_MakeAvailable(libassert)
target_link_libraries (your_target libassert::assert)
# On windows copy libassert.dll to the same directory as the executable for your_target
if ( WIN32 )
add_custom_command (
TARGET your_target POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:libassert::assert>
$<TARGET_FILE_DIR:your_target>
)
endif () -DCMAKE_BUILD_TYPE=Debug 또는 -DDCMAKE_BUILD_TYPE=RelWithDebInfo 로 구성하십시오.
MacOS에서 .dsym 파일을 생성하는 것이 좋습니다. 아래 플랫폼 물류를 참조하십시오.
패키지 관리자 또는 시스템 전체의 설치와 같은 라이브러리를 사용하는 다른 방법은 아래 사용법을 참조하십시오.
기본적으로 주장의 역할은 소프트웨어에서 내려진 가정을 확인하고 출처에 가까운 위반을 식별하는 것입니다. Assertion Tooling은 빠른 심사를 위해 개발자에게 가능한 많은 정보와 컨텍스트를 제공하는 데 우선 순위를 정해야합니다. 불행히도 기존 언어 및 라이브러리 툴링은 매우 제한된 심사 정보를 제공합니다.
예를 들어 stdlib Assertions assert(n <= 12); 실패한 이유 또는 실패로 이어지는 것에 대한 실패에 대한 정보를 제공하지 않습니다. 스택 추적을 제공하고 n Greatley의 가치를 제공하면 심사 및 디버깅이 향상됩니다. 이상적으로 어설 션 실패는 문제를 정확히 파악하기 위해 프로그래머가 디버거에서 재확인 할 필요가없는 충분한 진단 정보를 제공해야합니다.
이 라이브러리의 버전 1은 유용한 정보와 기능이 어설 션에 포장되어 개발자에게 빠르고 쉬운 인터페이스를 제공 할 수있는 방법을 살펴 보는 탐구였습니다.
이 라이브러리의 버전 2는 버전 1에서 배운 교훈을 가져와 개인적으로 개발할 수없는 도구를 만들어냅니다.
이 라이브러리가 지원하는 가장 중요한 기능은 자동 표현 분해입니다. ASSERT_LT 또는 기타 번거 로움이 필요하지 않습니다 assert(vec.size() > 10); 위에 표시된대로 자동으로 이해됩니다.
어제 표현과 관련된 값이 표시됩니다. 2 => 2 와 같은 중복 진단은 피합니다.
DEBUG_ASSERT (map.count( 1 ) == 2);
매크로 호출에서 전체 어제 표현 만 추출 할 수 있습니다. 표현식의 어떤 부분이 어떤 값에 해당하는지를 보여줍니다. 기본 표현식 구문 분석이 필요합니다. C ++ 문법은 모호하지만 대부분의 표현은 명확하지 않을 수 있습니다.
이 라이브러리의 모든 주장은 선택적 진단 메시지와 임의의 기타 진단 메시지를 지원합니다.
FILE* f = ASSERT_VAL(fopen(path, " r " ) != nullptr , " Internal error with foobars " , errno, path); errno 에 대한 특수 처리가 제공되며 Strerror는 자동으로 호출됩니다.
참고 : 추가 진단은 주장의 고장 경로에서만 평가됩니다.

예쁜 스택 트레이스를 생성하고 가능한 한 멋지게 포맷하는 데 많은 작업이 진행되었습니다. CPPTrace는 스택 트레이스 프리 C ++ 23을위한 휴대용 및 자체 포함 된 솔루션으로 사용됩니다. 선택적 구성은 라이브러리 문서에서 찾을 수 있습니다.
주목할만한 특징 중 하나는 항상 전체 경로를 인쇄하는 대신 경로를 차별화하는 데 필요한 최소 디렉토리 만 인쇄한다는 것입니다.

지적할만한 또 다른 기능은 스택 트레이스가 깊은 재귀로 흔적을 접을 수 있다는 것입니다.

Assertion Handler는 위의 모든 스크린 샷에서 볼 수 있듯이 적절한 곳에서 구문 강조 표시를 적용합니다. 이는 가독성을 높이는 데 도움이됩니다.
Libassert는 사용자 정의 어제 실패 핸들러를 지원합니다.
void handler (assert_type type, const assertion_info& assertion) {
throw std::runtime_error ( " Assertion failed: n " + assertion. to_string ());
}
int main () {
libassert::set_failure_handler (handler);
} 가능한 한 효과적으로 값의 디버그 문자열을 생성하는 데 많은주의를 기울입니다. 문자열, 문자, 숫자, 모두 예상대로 인쇄해야합니다. 또한 컨테이너, 튜플, std :: 옵션, 스마트 포인터 등은 모두 가능한 한 많은 정보를 표시하도록 연결되어 있습니다. 사용자 정의 유형이 오버로드 operator<<(std::ostream& o, const S& s) 가 오버로드가 호출됩니다. 그렇지 않으면 기본 메시지가 인쇄됩니다. 또한, stringification customiztaion 포인트가 제공됩니다.
template <> struct libassert ::stringifier<MyObject> {
std::string stringify ( const MyObject& type) {
return ...;
}
};

어설 션 값은 16 진수 또는 이진으로 인쇄 될뿐만 아니라 10 진수/바이너리가 어설 션 표현의 양쪽에 사용되는 경우 10 진수로 인쇄됩니다.
ASSERT (get_mask() == 0b00001101);
표현식이 이미 자동으로 분해되고 있으므로 -DLIBASSERT_SAFE_COMPARISONS 를 사용하여 부호 안전으로 자동으로 수행 된 서명되지 않은 비교를 선택할 수 있습니다.
ASSERT ( 18446744073709551606ULL == - 10 );
Libassert는 Catch2 및 Googletest와 함께 사용하기 위해 두 개의 헤더 <libassert/assert-catch2.hpp> 와 <libassert/assert-gtest.hpp> 제공합니다.
GTEST의 출력 예 :

아래의 자세한 정보.
Libassert는 세 가지 유형의 주장을 제공하며, 각각은 확인해야 할 시점과 해석 방법에 따라 약간 다양합니다.
| 이름 | 효과 |
|---|---|
DEBUG_ASSERT | Debug에서 확인, Codegen이 출시되지 않았습니다 |
ASSERT | 디버그 및 릴리스 빌드를 모두 확인했습니다 |
ASSUME | Debug, if(!(expr)) { __builtin_unreachable(); } 릴리스 중 |
무조건적인 주장
| 이름 | 효과 |
|---|---|
PANIC | 디버그와 릴리스에서 트리거합니다 |
UNREACHABLE | 디버그에서 트리거되어 릴리스에서는 도달 할 수없는 것으로 표시됩니다. |
ASSERT(false, ...) 보다 PANIC UNREACHABLE 에 대한 이점 중 하나는 컴파일러가 [[noreturn]] 정보를 얻는다는 것입니다.
실패 경로를 ASSUME 에서는 미지의 것으로 표시하여 최적화에 유용한 정보를 제공 할 수 있습니다. 이의 즉각적인 결과는 -DNDEBUG 의 어설 션 실패가 UB로 이어질 수 있고 이것을 매우 명확하게 만드는 것이 좋습니다.
FILE* file = ASSERT_VAL(fopen(path, "r"), "Failed to open file"); , 또한 사용할 수 있습니다 :
| 이름 | 효과 |
|---|---|
DEBUG_ASSERT_VAL | Debug에서 확인 된 Debug 및 Release에서 평가해야합니다. |
ASSERT_VAl | 디버그 및 릴리스 빌드를 모두 확인했습니다 |
ASSUME_VAL | Debug, if(!(expr)) { __builtin_unreachable(); } 릴리스 중 |
참고 : 릴리스에서도 DEBUG_ASSERT_VAL 와 달리 DEBUG_ASSERT 의 표현식은 여전히 평가되어야합니다. 물론 결과가 사용되지 않고 부작용이 발생하지 않으면 최적화됩니다.
성능 : 런타임 성능이 진행되는 한, 캘리포니아의 영향은 -Og 에서 매우 최소입니다. 코드의 빠른 경로 (즉, 어설 션이 실패하지 않는 곳)는 빠릅니다. 어설 션 실패가 발생하면 많은 작업이 필요합니다. 그러나 실패는 드물기 때문에 이것은 중요하지 않습니다.
컴파일 속도 : ,이 라이브러리의 마법에 필요한 모든 템플릿 인스턴스화와 관련된 컴파일 타임 비용이 있습니다.
다른:
메모
발현 분해로 인해 ASSERT(1 = 2); 컴파일.
모든 주장 기능은 매크로입니다. 다음은 그들과 인터페이스를위한 의사 결정을 다음과 같습니다.
void DEBUG_ASSERT (expression, [optional message], [optional extra diagnostics, ...]);
void ASSERT (expression, [optional message], [optional extra diagnostics, ...]);
void ASSUME (expression, [optional message], [optional extra diagnostics, ...]);
decltype ( auto ) DEBUG_ASSERT_VAL(expression, [optional message], [optional extra diagnostics, ...]);
decltype ( auto ) ASSERT_VAL (expression, [optional message], [optional extra diagnostics, ...]);
decltype ( auto ) ASSUME_VAL (expression, [optional message], [optional extra diagnostics, ...]);
void PANIC ([optional message], [optional extra diagnostics, ...]);
void UNREACHABLE ([optional message], [optional extra diagnostics, ...]); -DLIBASSERT_PREFIX_ASSERTIONS 사용 하여이 매크로를 LIBASSERT_ 로 접두사 할 수 있습니다. 이것은 Libassert Assertions를 포장하는 데 유용합니다.
-DLIBASSERT_LOWERCASE debug_assert 활성화하고 DEBUG_ASSERT 및 ASSERT 에 대한 별칭을 assert 데 사용될 수 있습니다. 참조 : <cassert> 교체.
expression 진단 정보가 제공 될 수 있으므로 expression 자동으로 분해됩니다. 결과 유형은 부울로 전환 할 수 있어야합니다.
표현식 트리에서 최상위 작업의 왼쪽과 오른쪽 사이의 작업은 기능 객체에 의해 평가됩니다.
참고 : 부울 논리 연산자 ( && 및 || )는 단락으로 인해 기본적으로 분해되지 않습니다.
assertion message 선택적 어설 션 메시지가 제공 될 수 있습니다. 어설 션 표현식 또는 공황/미지의 첫 번째 인수에 따른 첫 번째 인수가 모든 문자열 유형이라면 메시지로 사용됩니다 (문자열이되는 첫 번째 매개 변수를 원한다면 추가 진단 값이 먼저 빈 문자열을 전달하려면 ie ASSERT(foo, "", str); );
참고 : 어설 션 메시지 표현식은 어설 션의 실패 경로에서만 평가됩니다.
extra diagnostics임의의 수의 추가 진단 값이 제공 될 수 있습니다. 검사가 실패하면 표현 진단 아래에 표시됩니다.
참고 : 추가 진단은 어설 션의 고장 경로에서만 평가됩니다.
errno 제공 될 때 특수 취급이 있습니다. strerror 의 값이 자동으로 표시됩니다.
코드로의 통합 용이성을 용이하게하기 위해 _VAL 변형이 제공되어 Assert 표현식에서 값을 반환합니다. 반환 된 값은 다음과 같이 결정됩니다.
ASSERT_VAL(foo()); 또는 ASSERT_VAL(false); )에서와 같이, 표현의 값은 간단하게 반환됩니다.== ,! != , < , <= , > , >= , && , || 인 경우 , 또는 할당 또는 복합 할당이 다음 왼쪽 피연산자 의 값이 반환됩니다.& , | , ^ , << , >> 또는 비트 시프트 위의 우선 순위가있는 이진 연산자가 전체 표현식의 값을 반환합니다. 즉, ASSERT_VAL(foo() > 2); foo() 및 ASSERT_VAL(x & y); x & y 의 계산 된 결과를 반환합니다.
반환하기 위해 선택된 어설 션 표현식의 값이 lValue 인 경우, 어설 션 호출 유형은 lvalue 참조가됩니다. 어설 션 표현식의 값이 rvalue 인 경우 호출 유형은 rvalue가됩니다.
namespace libassert {
[[nodiscard]] std::string stacktrace (
int width = 0 ,
const color_scheme& scheme = get_color_scheme(),
std::size_t skip = 0
);
template < typename T> [[nodiscard]] std::string_view type_name () noexcept ;
template < typename T> [[nodiscard]] std::string pretty_type_name () noexcept ;
template < typename T> [[nodiscard]] std::string stringify ( const T& value);
}stacktrace : 스택 추적, 주어진 너비의 형식을 생성합니다 (너비 형식 없음의 경우 0)type_name : t의 유형 이름을 반환합니다pretty_type_name : t에 대한 예열 된 유형 이름을 반환합니다stringify : 값의 디버그 문자열을 생성합니다 namespace libassert {
void enable_virtual_terminal_processing_if_needed ();
inline constexpr int stdin_fileno = 0 ;
inline constexpr int stdout_fileno = 1 ;
inline constexpr int stderr_fileno = 2 ;
bool isatty ( int fd);
[[nodiscard]] int terminal_width ( int fd);
}enable_virtual_terminal_processing_if_needed : 색상 출력에 필요한 Windows의 터미널에 ANSI 이스케이프 시퀀스를 활성화합니다.isatty : 파일 디스크립터가 터미널에 해당하는 경우 true를 반환합니다.terminal_width : 오류에서 FD 또는 0으로 표시되는 터미널의 너비를 반환합니다. namespace libassert {
// NOTE: string view underlying data should have static storage duration, or otherwise live as
// long as the scheme is in use
struct color_scheme {
std::string_view string, escape, keyword, named_literal, number, punctuation, operator_token,
call_identifier, scope_resolution_identifier, identifier, accent, unknown, reset;
static const color_scheme ansi_basic;
static const color_scheme ansi_rgb;
static const color_scheme blank;
};
void set_color_scheme ( const color_scheme&);
const color_scheme& get_color_scheme ();
} 기본적으로 color_scheme::ansi_rgb 사용됩니다. 색상을 비활성화하려면 color_scheme::blank 사용하십시오.
set_color_scheme : stderr가 터미널 일 때 기본 어시스트 핸들러의 색 구성표를 설정합니다. namespace libassert {
void set_separator (std::string_view separator);
}set_separator : 어설 션 진단 출력에서 표현식과 값 사이의 분리기를 설정합니다. 기본값 : => . 참고 : 스레드 안전이 아닙니다. namespace libassert {
enum class literal_format_mode {
infer, // infer literal formats based on the assertion condition
no_variations, // don't do any literal format variations, just default
fixed_variations // always use a fixed set of formats (in addition to the default format)
};
void set_literal_format_mode (literal_format_mode);
enum class literal_format : unsigned {
// integers and floats are decimal by default, chars are of course chars, and everything
// else only has one format that makes sense
default_format = 0 ,
integer_hex = 1 ,
integer_octal = 2 ,
integer_binary = 4 ,
integer_character = 8 , // format integers as characters and characters as integers
float_hex = 16 ,
};
[[nodiscard]] constexpr literal_format operator |(literal_format a, literal_format b);
void set_fixed_literal_format (literal_format);
}set_literal_format_mode : 라이브러리에 문자 그대로 변형이 표시되어야하는지 여부를 설정합니다.set_fixed_literal_format : 고정 된 문자 형식 구성을 설정하고 Literal_format_mode를 자동으로 변경합니다. 기본 형식은 항상 다른 형식과 함께 사용됩니다. namespace libassert {
enum class path_mode {
full, // full path is used
disambiguated, // only enough folders needed to disambiguate are provided
basename, // only the file name is used
};
LIBASSERT_EXPORT void set_path_mode (path_mode mode);
}set_path_mode : 어설 션 출력에 대한 경로 단축 모드를 설정합니다. 기본값 : path_mode::disambiguated . namespace libassert {
enum class assert_type {
debug_assertion,
assertion,
assumption,
panic,
unreachable
};
struct LIBASSERT_EXPORT binary_diagnostics_descriptor {
std::string left_expression;
std::string right_expression;
std::string left_stringification;
std::string right_stringification;
};
struct extra_diagnostic {
std::string_view expression;
std::string stringification;
};
struct LIBASSERT_EXPORT assertion_info {
std::string_view macro_name;
assert_type type;
std::string_view expression_string;
std::string_view file_name;
std:: uint32_t line;
std::string_view function;
std::optional<std::string> message;
std::optional<binary_diagnostics_descriptor> binary_diagnostics;
std::vector<extra_diagnostic> extra_diagnostics;
size_t n_args;
std::string_view action () const ;
const cpptrace::raw_trace& get_raw_trace () const ;
const cpptrace::stacktrace& get_stacktrace () const ;
[[nodiscard]] std::string header ( int width = 0 , const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string tagline ( const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string location () const ;
[[nodiscard]] std::string statement ( const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string print_binary_diagnostics ( int width = 0 , const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string print_extra_diagnostics ( int width = 0 , const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string print_stacktrace ( int width = 0 , const color_scheme& scheme = get_color_scheme()) const ;
[[nodiscard]] std::string to_string ( int width = 0 , const color_scheme& scheme = get_color_scheme()) const ;
};
} Debug Assertion failed at demo.cpp:194: void foo::baz(): Internal error with foobars
debug_assert(open(path, 0) >= 0, ...);
Where:
open(path, 0) => -1
Extra diagnostics:
errno => 2 "No such file or directory"
path => "/home/foobar/baz"
Stack trace:
#1 demo.cpp:194 foo::baz()
#2 demo.cpp:172 void foo::bar<int>(std::pair<int, int>)
#3 demo.cpp:396 main
Debug Assertion failed : assertion_info.action()demo.cpp:194 : assertion_info.file_name 및 assertion_info.linevoid foo::baz() : assertion_info.pretty_functionInternal error with foobars : assertion_info.messagedebug_assert : assertion_info.macro_nameopen(path, 0) >= 0 : assertion_info.expression_string... : assertion_info.n_args 에 의해 결정된 총 인수 수가 Assertion Macro에 전달 된open(path, 0) : assertion_info.binary_diagnostics.left_expression-1 : assertion_info.binary_diagnostics.left_stringification0 => 0 유용하지 않기 때문에이 경우 생략)errno : assertion_info.extra_diagnostics[0].expression2 "No such file or directory" : assertion_info.extra_diagnostics[0].stringificationassertion_info.get_stacktrace() 또는 assertion_info.get_raw_trace() 해결하지 않고 추적을 얻을 수 있습니다.도우미 :
assertion_info.header() :
Debug Assertion failed at demo.cpp:194: void foo::baz(): Internal error with foobars
debug_assert(open(path, 0) >= 0, ...);
Where:
open(path, 0) => -1
Extra diagnostics:
errno => 2 "No such file or directory"
path => "/home/foobar/baz"
assertion_info.tagline() :
Debug Assertion failed at demo.cpp:194: void foo::baz(): Internal error with foobars
assertion_info.location() :
메모
경로 처리는 경로 모드에 따라 수행됩니다.
demo.cpp:194
assertion_info.statement() :
debug_assert(open(path, 0) >= 0, ...);
assertion_info.print_binary_diagnostics() :
Where:
open(path, 0) => -1
assertion_info.print_extra_diagnostics() :
Extra diagnostics:
errno => 2 "No such file or directory"
path => "/home/foobar/baz"
assertion_info.print_stacktrace() :
Stack trace:
#1 demo.cpp:194 foo::baz()
#2 demo.cpp:172 void foo::bar<int>(std::pair<int, int>)
#3 demo.cpp:396 main
Libassert는 사용자 정의 유형에 대한 사용자 정의 지점을 제공합니다.
template <> struct libassert ::stringifier<MyObject> {
std::string stringify ( const MyObject& type) {
return ...;
}
};기본적으로 컨테이너와 같은 사용자 정의 유형은 자동으로 stringified됩니다.
또한 LIBASSERT_USE_FMT 사용하여 libassert가 fmt::formatter s를 사용할 수 있습니다.
마지막으로, 타조 operator<< 오버로드를 문자화할 수 있습니다.
namespace libassert {
void set_failure_handler ( void (*handler)( const assertion_info&));
}set_failure_handler : 프로그램의 어설 션 핸들러를 설정합니다.기본 핸들러와 유사한 예제 어설 션 처리기 :
void libassert_default_failure_handler ( const assertion_info& info) {
libassert::enable_virtual_terminal_processing_if_needed (); // for terminal colors on windows
std::string message = info. to_string (
libassert::terminal_width (libassert::stderr_fileno),
libassert::isatty (libassert::stderr_fileno)
? libassert::get_color_scheme ()
: libassert::color_scheme::blank
);
std::cerr << message << std::endl;
switch (info. type ) {
case libassert::assert_type::assertion:
case libassert::assert_type::debug_assertion:
case libassert::assert_type::assumption:
case libassert::assert_type::panic:
case libassert::assert_type::unreachable:
( void ) fflush (stderr);
std::abort ();
// Breaking here as debug CRT allows aborts to be ignored, if someone wants to make a
// debug build of this library
break ;
default :
std::cerr << " Critical error: Unknown libassert::assert_type " << std::endl;
std::abort ( 1 );
}
}기본적으로 Libassert는 모든 주장 유형에서 중단됩니다. 그러나 낙태하는 대신 일부 또는 모든 주장 유형에서 예외를 던지는 것이 바람직 할 수 있습니다.
중요한
실패 핸들러는 assert_type::panic and assert_type::unreachable 반환해서는 안됩니다.
Libassert는 Callstack의 여러 층과는 달리 어설 션 라인을 깨뜨려 어설거를보다 친숙하게 만들지 않는 주장 실패에 대한 프로그래밍 방식의 브레이크 포인트를 지원합니다.

이 기능은 현재 옵트 인이며 LIBASSERT_BREAK_ON_FAIL 정의하여 활성화 할 수 있습니다. 컴파일러 플래그 : -DLIBASSERT_BREAK_ON_FAIL 또는 /DLIBASSERT_BREAK_ON_FAIL 로 가장 잘 수행됩니다.
내부적으로 라이브러리는 디버거 브레이크 포인트에 대한 지침을 실행하기 전에 디버거의 사전을 확인합니다. 기본적으로 수표는 첫 번째 어설 션 실패에서 한 번만 수행됩니다. 일부 시나리오에서는이 점검을 항상 수행하도록 구성하는 것이 바람직 할 수 있습니다. 예를 들어, 예외를 중단하는 대신 예외를 던지는 사용자 정의 어제 처리기를 사용하고 나중에 추가 실패를 허용하고 프로그램 실행을 통해 디버거 파트 웨이 만 첨부 할 수 있습니다. libassert::set_debugger_check_mode 사용 하여이 점검이 수행되는 방법을 제어 할 수 있습니다.
namespace libassert {
enum class debugger_check_mode {
check_once,
check_every_time,
};
void set_debugger_check_mode (debugger_check_mode mode) noexcept ;
}도서관은 또한 중단 점을 설정하고 프로그램이 디버깅되는지 확인하기위한 내부 유틸리티를 노출시킵니다.
namespace libassert {
bool is_debugger_present () noexcept ;
}
# define LIBASSERT_BREAKPOINT () <...internals...>
# define LIBASSERT_BREAKPOINT_IF_DEBUGGING () <...internals...>이 API는 p2514의 API를 모방하며, 이는 C ++ 26에 허용됩니다.
constexpr 에 대한 참고 사항 : Clang과 MSVC Libassert는 컴파일러 내입을 사용할 수 있지만 GCC 인라인 어셈블리가 필요합니다. ConstexPR 기능에서는 인라인 어셈블리가 허용되지 않지만 GCC는 GCC 10 이후 경고를 통해이를 지원하며 라이브러리는 GCC 12에 대한 경고를 눌릴 수 있습니다.
정의 :
LIBASSERT_USE_MAGIC_ENUM : 열거 값을 줄이기 위해 Magic Enum을 사용하십시오LIBASSERT_DECOMPOSE_BINARY_LOGICAL : decompose && 및 ||LIBASSERT_SAFE_COMPARISONS : 분해 된 표현식에 대한 안전한 서명되지 않은 비교를 활성화합니다LIBASSERT_PREFIX_ASSERTIONS : LIBASSERT_ 와의 모든 주장 매크로 접두사LIBASSERT_USE_FMT : libfmt 통합을 활성화합니다LIBASSERT_NO_STRINGIFY_SMART_POINTER_OBJECTS : 스마트 포인터 내용의 문자열 화를 비활성화합니다cmake :
LIBASSERT_USE_EXTERNAL_CPPTRACE : externam cpptrace를 사용하여 라이브러리를 가져 오는 대신 가져 오기LIBASSERT_USE_EXTERNAL_MAGIC_ENUM : 도서관을 가져 오는 대신 externam magic enum을 사용하여 가져 오기메모
MSVC의 부적합 전처리 기 때문에 어설 션 포장지를 제공하는 쉬운 방법은 없습니다. 테스트 라이브러리 통합 /Zc:preprocessor 필요합니다.
Libassert는 libassert/assert-catch2.hpp 에서 Catch2 통합을 제공합니다.
# include < libassert/assert-catch2.hpp >
TEST_CASE ( " 1 + 1 is 2 " ) {
ASSERT ( 1 + 1 == 3 );
}
현재 제공되는 유일한 매크로는 ASSERT 이며, 이는 내부적으로 REQUIRE 수행 할 것입니다.
참고 : v3.6.0 전에 ANSI 색상 코드는 Catch2의 선 랩핑을 방해하여 기존 버전에서 색상이 비활성화됩니다.
Libassert는 libassert/assert-gtest.hpp 에서 Gtest 통합을 제공합니다.
# include < libassert/assert-gtest.hpp >
TEST (Addition, Arithmetic) {
ASSERT ( 1 + 1 == 3 );
}
현재 Libassert는 GTEST에 대한 ASSERT 및 EXPECT Macros를 제공합니다.
이것은 내가 원하는만큼 예쁘지는 않지만 작업이 완료됩니다.
이 라이브러리는> = C ++ 17을 대상으로하며 모든 주요 컴파일러 및 모든 주요 플랫폼 (Linux, MacOS, Windows 및 MingW)을 지원합니다.
참고 : 라이브러리는 일부 컴파일러 확장 및 컴파일러 특정 기능에 의존하므로 -pedantic 과 호환되지 않습니다.
Cmake FetchContent와 함께 :
include (FetchContent)
FetchContent_Declare(
libassert
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git
GIT_TAG v2.1.2 # <HASH or TAG>
)
FetchContent_MakeAvailable(libassert)
target_link_libraries (your_target libassert::assert)참고 : Windows 및 MacOS에서는 일부 추가 작업이 권장됩니다. 아래 플랫폼 물류를 참조하십시오.
-DCMAKE_BUILD_TYPE=Debug 또는 -DDCMAKE_BUILD_TYPE=RelWithDebInfo 로 구성하십시오.
git clone https://github.com/jeremy-rifkin/libassert.git
git checkout v2.1.2
mkdir libassert/build
cd libassert/build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
sudo make installCmake를 통해 사용 :
find_package (libassert REQUIRED)
target_link_libraries (<your target > libassert::assert) -DCMAKE_BUILD_TYPE=Debug 또는 -DDCMAKE_BUILD_TYPE=RelWithDebInfo 로 구성하십시오.
또는 -lassert 로 컴파일 :
g++ main.cpp -o main -g -Wall -lassert
./main라인을 따라 오류가 발생하면
error while loading shared libraries: libassert.so: cannot open shared object file: No such file or directory
필요한 링크를 생성하고 캐시를 업데이트하려면 sudo /sbin/ldconfig 실행해야 할 수도 있으므로 시스템에서 libcpptrace.so를 찾을 수 있습니다 (Ubuntu에서이를 수행해야했습니다). 시스템 전체를 설치할 때만. 일반적으로 귀하의 패키지 관리자는 새 라이브러리를 설치할 때이를 수행합니다.
git clone https: // github.com / jeremy - rifkin / libassert.git
git checkout v2. 1.2
mkdir libassert / build
cd libassert / build
cmake . . - DCMAKE_BUILD_TYPE = Release
msbuild libassert.sln
msbuild INSTALL.vcxproj참고 : 개발자 PowerShell에서 관리자로 실행하거나 vcvarsall.bat를 사용하여 Visual Studio와 함께 배포하여 올바른 환경 변수를 설정해야합니다.
로컬 사용자 (또는 사용자 정의 접두사)를 위해 설치하려면 :
git clone https://github.com/jeremy-rifkin/libassert.git
git checkout v2.1.2
mkdir libassert/build
cd libassert/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX= $HOME /wherever
make -j
sudo make installCmake를 통해 사용 :
find_package (libassert REQUIRED PATHS $ENV{HOME} /wherever)
target_link_libraries (<your target > libassert::assert)수동으로 사용 :
g++ main.cpp -o main -g -Wall -I$HOME/wherever/include -L$HOME/wherever/lib -lassert
CMAKE없이 라이브러리를 사용하려면 먼저 시스템 전체 설치, 로컬 사용자 설치 또는 패키지 관리자시 설치 지침을 따르십시오.
다음 인수를 사용하여 libassert와 함께 컴파일하십시오.
| 컴파일러 | 플랫폼 | 의존성 |
|---|---|---|
| GCC, Clang, Intel 등 | Linux/MacOS/Unix | -libassert -I[path] [cpptrace args] |
| mingw | 창 | -libassert -I[path] [cpptrace args] |
| MSVC | 창 | assert.lib /I[path] [cpptrace args] |
| 그 소리 | 창 | -libassert -I[path] [cpptrace args] |
-i [ [path] -I[path] 및 /I[path] 의 [Path] 자리 표시기의 경우 libassert/assert.hpp 포함하는 폴더에 대한 경로를 지정하십시오.
정적으로 연결하는 경우 -DLIBASSERT_STATIC_DEFINE 지정해야합니다.
[cpptrace args] 자리 표시자는 CPPTrace 문서를 참조하십시오.
Libassert는 Conan (https://conan.io/center/recipes/libassert)을 통해 구입할 수 있습니다.
[requires]
libassert/2.1.2
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
# ...
find_package (libassert REQUIRED)
# ...
target_link_libraries (YOUR_TARGET libassert::assert) vcpkg install libassert
find_package (libassert CONFIG REQUIRED)
target_link_libraries (YOUR_TARGET PRIVATE libassert::assert)Windows와 MacO는 모든 것을 올바른 장소에 가져 오려면 약간의 추가 작업이 필요합니다.
Windows에서 Library 복사 .dll :
# Copy the assert.dll on windows to the same directory as the executable for your_target.
# Not required if static linking.
if ( WIN32 )
add_custom_command (
TARGET your_target POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:libassert::assert>
$<TARGET_FILE_DIR:your_target>
)
endif ()MacOS에서는 프로그램에 대한 디버그 정보가 포함 된 DSYM 파일을 생성하는 것이 좋습니다.
Xcode Cmake에서는이 작업을 수행 할 수 있습니다
set_target_properties (your_target PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" ) 그리고 Xcode 외부 이것은 dsymutil yourbinary 로 수행 할 수 있습니다.
# Create a .dSYM file on macos. Currently required, but hopefully not for long
if ( APPLE )
add_custom_command (
TARGET your_target
POST_BUILD
COMMAND dsymutil $<TARGET_FILE:your_target>
)
endif () 이 라이브러리는 <cassert> 의 드롭 인 교체가 아닙니다. -DLIBASSERT_LOWERCASE 어설 션 매크로에 대한 소문자 별칭을 만드는 데 사용될 수 있지만 Libassert의 ASSERT 여전히 릴리스에서 확인된다는 것을 알고 있어야합니다. <cassert> Libassert로 바꾸려면 assert DEBUG_ASSERT 로 바꾸거나 다음 줄을 따라 별명을 만듭니다.
# define assert (...) DEBUG_ASSERT(__VA_ARGS__) 알아야 할 한 가지 : Cassert의 assert 우선하는 것은 기술적으로 표준에 의해 허용되지 않지만, 이것은 세인트 컴파일러에게는 문제가되지 않아야합니다.
아니, 아직.
cpp-sort assert_eq 와 같은 구성이 있더라도 Assertion Diagnostics는 종종 부족합니다. 예를 들어, 녹에서 왼쪽과 오른쪽 값은 표시되지만 표현 자체는 표시되지 않습니다.
fn main ( ) {
let count = 4 ;
assert_eq ! ( count , 2 ) ;
} thread 'main' panicked at 'assertion failed: `(left == right)`
left: `4`,
right: `2`', /app/example.rs:3:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
이것은 가능한 한 도움이되지 않습니다.
기능성 기타 언어 / 표준 라이브러리가 제공합니다.
| C/C ++ | 녹 | 기음# | 자바 | 파이썬 | 자바 스크립트 | Libassert | |
|---|---|---|---|---|---|---|---|
| 표현 문자열 | ✔️ | ✔️ | |||||
| 위치 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| 스택 추적 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
| 주장 메시지 | ** | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| 추가 진단 | * | * | * | * | ✔️ | ||
| 이진 전문화 | ✔️ | ✔️ | ✔️ | ||||
| 자동 표현 분해 | ✔️ | ||||||
| 하위 표현 문자열 | ✔️ |
* : 문자열 형식을 통해 가능하지만 이는 비밀입니다.
** : assert(expression && "message") 일반적으로 사용되지만 이는 하위 이기적이며 문자열 리터럴 메시지 만 허용합니다.
엑스트라 :
| C/C ++ | 녹 | 기음# | 자바 | 파이썬 | 자바 스크립트 | Libassert | |
|---|---|---|---|---|---|---|---|
| 구문 강조 표시 | ? | ✔️ | |||||
| 문자형 서식 일관성 | ✔️ | ||||||
| 발현 문자열 및 발현 값은 어디에서나 | ✔️ | ||||||
| 어설 션이 표현식에 인라인으로 통합 될 수 있도록 어설 션의 반환 값 | ✔️ |