xassert
¾ÆÁ÷ ¿ÏÀüÇÏÁö ¾ÊÀº ³»¿ëÀÔ´Ï´Ù. ¼öÁ¤Çϱâ Àü¿¡ CCodeSnippets¸¦ Àоî Áֽñ⠹ٶø´Ï´Ù. -- cinsk
Description ¶¸¸¾à <xassert.h>¸¦ Æ÷ÇÔÇÒ ¶§, NDEBUG ¸ÅÅ©·Î°¡ Á¤ÀǵǾî ÀÖÀ¸¸é xassert()´Â ¾Æ¹«·± ÀÏÀ» ÇÏÁö ¾ÊÀ¸¸ç, NDEBUG°¡ Á¤ÀǵǾî ÀÖÁö ¾ÊÀ¸¸é, printf(3) ½ºÅ¸ÀÏÀÇ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» Á¦¿ÜÇÏ°í, assert(3)¿Í ¶È°°ÀÌ µ¿ÀÛÇÑ´Ù.
Note ¶ISO C¸¦ Áö¿øÇÏ´Â ½Ã½ºÅÛ¿¡¼ ¾µ ¼ö ÀÖ´Ù. Á¤È®È÷ ¸»Çϸé, ¸ÅÅ©·Î VA_ARGS¸¦ Áö¿øÇÏ´Â ÄÄÆÄÀÏ·¯¿¡¼ ¾µ ¼ö ÀÖ´Ù.
Introduction ¶assert(3)´Â °³¹ßÀÚ°¡ ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¶§, ¹ö±×°¡ »ý±â´Â °ÍÀ» ¸·¾ÆÁÖ´Â °¡Àå ±âÃÊÀûÀÎ ¹æ¹ý ÁßÀÇ ÇϳªÀÔ´Ï´Ù.
TODO: assert()¿¡ ´ëÇؼ Á» ´õ ¼³¸í
assert(3)ÀÇ Ãâ·ÂÀº Á¤ÇØÁöÁö ¾Ê¾Æ¼, ÄÄÆÄÀÏ·¯¸¶´Ù Á¶±Ý¾¿ ´Ù¸¨´Ï´Ù¸¸1, ´ë°³ÀÇ °æ¿ì, assert°¡ ¹ß»ýµÈ ¼Ò½ºÀÇ ÆÄÀÏ À̸§°ú ÁÙ ¹øÈ£¸¦ ¾Ë·ÁÁÖ¸é¼ ÇÁ·Î±×·¥À» °Á¦·Î ³¡³À´Ï´Ù. ³¡³¾ ¶§¿¡´Â abort(3)¸¦ »ç¿ëÇϵµ·Ï µÇ¾î ÀÖ½À´Ï´Ù.
¿¹¸¦ µé¾î ¾Æ·¡ÀÇ Ãâ·ÂÀº ¾î¶² ½Ã½ºÅÛÀÇ assert(3) Ãâ·Â °á°úÀÔ´Ï´Ù.
$ cat tmp.c #include <assert.h> void adult_only(int age) { assert(age > 18); } int main(void) { adult_only(3); return 0; } $ gcc tmp.c $ ./a.out a.out: tmp.c:6: adult_only: Assertion `age > 18' failed. Aborted $ _assert()¸¦ È¿°úÀûÀ¸·Î ¼öÇàÇϱâ À§Çؼ, °³¹ßÀÚ°¡ Á÷Á¢ ¸Þ½ÃÁö¸¦ ½á ³ÖÀ» ¼ö ÀÖÀ¸¸é Âü ÆíÇÒ °ÍÀ̶ó »ý°¢ÇÕ´Ï´Ù. Áï ´Ü¼øÈ÷ ¾î¶² ¼ö½Ä(À§¿¡¼´Â "age > 18")À» Ãâ·ÂÇÏ°í Á¾·áÇϱ⠺¸´Ù´Â, printf()¿Í °°Àº Çü½ÄÀÇ ¸Þ½ÃÁöµµ ÇÔ²² Ãâ·ÂÇÒ ¼ö ÀÖ´Ù¸é ³ªÁß¿¡ assert()°¡ ¹ß»ýÇÒ ¶§, ¿Ö ¹ß»ýÇß´ÂÁö ÀÌÀ¯¸¦ ºü¸£°Ô ¾Ë¾Æ³¾ ¼ö ÀÖÀ» °ÍÀÔ´Ï´Ù. °á±¹ ¿ì¸®°¡ ¸¸µé°íÀÚ ÇÏ´Â °ÍÀº ´ÙÀ½°ú °°Àº Äڵ带 ¸¸µé ¼ö ÀÖ°Ô ÇÏ°í:
xassert(age > 18, "AGE must be 19 at least. (age = %d)", age);
a.out: tmp.c:6: adult_only: Assertion `age > 18' failed. AGE must be 19 at least. (age = 3) Implementation ¶assert(3)´Â ¸ÅÅ©·Î NDEBUG°¡ Á¤ÀǵǾî ÀÖ´Â °æ¿ì, ((void)0)À¸·Î È®ÀåµÇ¾î ½ÇÁ¦·Î ±â°è¾î Äڵ带 ¸¸µé¾î³»Áö ¾Ê½À´Ï´Ù. µû¶ó¼ ÃÖ´ëÇÑ ¿À¹öÇìµå¸¦ Àû°Ô Çϱâ À§Çؼ´Â ASSERTµµ ´ÙÀ½°ú °°ÀÌ ¸ÅÅ©·Î ÇÔ¼ö·Î Á¤ÀǵǾî¾ß ÇÕ´Ï´Ù.
#ifndef NDEBUG
# define xassert(x, ...) /* ¸Þ½ÃÁö Ãâ·ÂÇÏ°í Á¾·á.. */ #else # define xassert(x, ...) ((void)0) #endif °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÏ´Â ¸ÅÅ©·Î¿¡ ´ëÇؼ´Â CLanguageVariableArgumentsList¿¡¼ ¼³¸íÇß½À´Ï´Ù. ±â¾ïÀÌ Àß ³ªÁö ¾Ê´Â´Ù¸é ´Ù½Ã Àо½Ã±â ¹Ù¶ø´Ï´Ù. ÀÌÁ¦ À§ Äڵ忡¼ ÁÖ¼® ºÎºÐÀ» ½á ³Ö¾î¾ß Çϴµ¥, ´ÙÀ½°ú °°Àº ÇÔ¼ö¸¦ ¸¸µé¾î¼ ´ëüÇÏ·Á°í ÇÕ´Ï´Ù.
void
assert_(const char *filename, int lineno, const char *funcname, const char *expr, const char *format, ...) { va_list ap; fflush(stdout); fprintf(stderr, "%s:%d: Assertion `%s' failed.\n", filename, lineno, expr); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); abort(); }
void assert_(const char *filename, int lineno,
const char *funcname, const char *expr, const char *format, ...); #define xassert(x, ...) do { \ if (!(x)) \ assert_(__FILE__, __LINE__, __func__, \ #x, __VA_ARGS__); \ } while (0) TODO: ¸î°¡Áö »ç¿ë·Ê Ãß°¡
xassert.h ¶
/* $Id: xassert,v 1.12 2005/03/22 06:56:28 kss Exp kss $ */
/* * Enhanced assert(3) * Copyright (C) 2003, 2004 Seong-Kook Shin <cinsk.shin at samsung.com> */ #ifndef XASSERT_H_ #define XASSERT_H_ #ifdef HAVE_CONFIG_H # include <config.h> #endif /* This indirect writing of extern "C" { ... } makes Emacs happy */ #ifndef BEGIN_C_DECLS # ifdef __cplusplus # define BEGIN_C_DECLS extern "C" { # define END_C_DECLS } # else # define BEGIN_C_DECLS # define END_C_DECLS # endif #endif /* BEGIN_C_DECLS */ BEGIN_C_DECLS #ifndef NDEBUG extern void assert_(const char *file, long line, const char *func, const char *expr, const char *format, ...); # define xassert(condition, ...) do { \ if (!(condition)) \ assert_(__FILE__, __LINE__, __func__, \ #condition, __VA_ARGS__); \ } while (0) #else # define xassert(condition, ...) ((void)0) #endif /* NDEBUG */ END_C_DECLS #endif /* XASSERT_H_ */ xassert.c ¶
/* $Id: xassert,v 1.12 2005/03/22 06:56:28 kss Exp kss $ */
/* * Enhanced assert(3) * Copyright (C) 2003, 2004 Seong-Kook Shin <cinsk.shin at samsung.com> */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <xassert.h> void assert_(const char *file, long line, const char *func, const char *expr, const char *format, ...) { va_list ap; fflush(stdout); fflush(stderr); /* possibly redundant */ fprintf(stderr, "%s:%ld: Assertion `%s' failed at %s.\n\t", file, line, expr, func); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); fflush(stderr); /* possibly redundant */ abort(); } #ifdef TEST_XASSERT int main(void) { int age = 1; ASSERT(age > 10, "Age should be larger than 10. (age = %d)", age); return 0; } #endif /* TEST_XASSERT */ |
A truly wise man never plays leapfrog with a Unicorn. |