Boost 소스 분석 -

Boost 소스 분석 -- < boost / assert. hpp >
마 동 량 Loki)
한 사람의 전쟁 (戰 爭)http://blog.csdn.net/MDL13412)
헤더 파일:
       
위치:        BOOST_ASSERT 는 표준 라 이브 러 리 의 assert 와 유사 하 며, Boost 라 이브 러 리 와 사용자 코드 에서 모두 사용 할 수 있 도록 정의 되 어 있 습 니 다.분석:        기본 상황 에서 BOOSTASSERT (expr) 는 assert (expr) 와 같 지만, \ # include < boost / assert. hpp > 전에 BOOST 를 정의 하면DISABLE_ASSERTS, 그럼 BOOSTASSERT (expr) 는 (void) 0 으로 이 루어 집 니 다. 즉, 아무것도 하지 않 고 컴 파일 러 는 쉽게 최적화 할 수 있 습 니 다.이렇게 하 는 장점 은 사용자 가 코드 를 작성 할 때 assert 에 영향 을 주지 않 는 전제 에서 일부 단언 을 켜 고 사용 하지 않 아 코드 에 더 많은 유연성 을 제공 할 수 있다 는 것 이다.        만약 BOOST 를 정의 했다 면ENABLE_ASSERT_HANDLER, Boost 라 이브 러 리 는 사용자 에 게 오류 가 발생 했 을 때 리 셋 함수 assertion 을 제공 합 니 다.failed, 사용자 스스로 실현 해 야 합 니 다.        BOOST_ASSERT_MSG 는 오류 가 발생 했 을 때 사용자 정의 오류 설명 정 보 를 추가 하여 사용자 가 오 류 를 잘 이해 하고 처리 할 수 있 도록 도와 줄 수 있 습 니 다.        BOOST 를 정의 하지 않 으 면ENABLE_ASSERT_HANDLER, 그럼 BOOSTASSERT_MSG 는 단언 과 관련 된 정 보 를 BOOST 에 전달 합 니 다.ASSERT_MSG_OSTREAM, 기본 값 은 std: cerr 이 고 다음 에 std:: abort () 를 호출 합 니 다.사용자 정의 출력 흐름 이 필요 하 다 면, 사용 자 는 < boost / assert. hpp > 를 포함 하기 전에 BOOST 를 지정 해 야 합 니 다.ASSERT_MSG_OSTREAM 의 값.        BOOST_VERIFY 의 기능 과 BOOSTASSERT 는 기본적으로 일치 하 며, 다른 것 은 BOOST 입 니 다.VERIFY 의 표현 식 은 항상 값 을 구 합 니 다. 즉, NDEBUG 와 BOOST 를 통 해DISABLE_ASSERTS 가 단언 을 사용 하지 않 을 때 표현 식 은 여전히 값 을 구하 지만 결 과 는 버 려 집 니 다.주의:         헤더 파일 guard 가 없습니다. 이 파일 을 여러 번 포함 할 때 서로 다른 매크로 를 미리 정의 하여 서로 다른 단언 을 실현 하기 위해 서 입 니 다.원본 분석:
//
//  boost/assert.hpp - BOOST_ASSERT(expr)
//                     BOOST_ASSERT_MSG(expr, msg)
//                     BOOST_VERIFY(expr)
//
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//  Copyright (c) 2007 Peter Dimov
//  Copyright (c) Beman Dawes 2011
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//  Note: There are no include guards. This is intentional.
//
//  See http://www.boost.org/libs/utility/assert.html for documentation.
//

//
// Stop inspect complaining about use of 'assert':
//
// boostinspect:naassert_macro
//

// Comment By:    
// E-mail:      [email protected]
// Blog:        http://blog.csdn.net/mdl13412  

//--------------------------------------------------------------------------------------//
//                                     BOOST_ASSERT                                     //
//--------------------------------------------------------------------------------------//

//         guard,         undef    ,           ,         。
#undef BOOST_ASSERT

//   BOOST_DISABLE_ASSERTS,    ,         assert
#if defined(BOOST_DISABLE_ASSERTS)

//             ,      ,           。。。          boost ^_^
# define BOOST_ASSERT(expr) ((void)0)

//    BOOST_ENABLE_ASSERT_HANDLER   ,        assertion_failed,         。
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)

#include <boost/current_function.hpp>

namespace boost
{
  void assertion_failed(char const * expr,
                        char const * function, char const * file, long line); // user defined
} // namespace boost

//    assert  ,   ,         ,               ,      。
// BOOST_CURRENT_FUNCTION          ,        , <boost/current_function.hpp>    。
#define BOOST_ASSERT(expr) ((expr) \
  ? ((void)0) \
  : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

  //      ,         assert,    NDEBUG BOOST_DISABLE_ASSERTS    。
#else
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
# define BOOST_ASSERT(expr) assert(expr)
#endif

//--------------------------------------------------------------------------------------//
//                                   BOOST_ASSERT_MSG                                   //
//--------------------------------------------------------------------------------------//

//   BOOST_ASSERT  , BOOST_ASSERT_MSG              ,
//           ,  、       ,    。
# undef BOOST_ASSERT_MSG

#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)

  #define BOOST_ASSERT_MSG(expr, msg) ((void)0)

#elif defined(BOOST_ENABLE_ASSERT_HANDLER)

  #include <boost/current_function.hpp>

  namespace boost
  {
    void assertion_failed_msg(char const * expr, char const * msg,
                              char const * function, char const * file, long line); // user defined
  } // namespace boost

  #define BOOST_ASSERT_MSG(expr, msg) ((expr) \
    ? ((void)0) \
    : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

#else
//   :       guard,              ,            。
  #ifndef BOOST_ASSERT_HPP
    #define BOOST_ASSERT_HPP
    #include <cstdlib>
    #include <iostream>
    #include <boost/current_function.hpp>

    //  IDE's like Visual Studio perform better if output goes to std::cout or
    //  some other stream, so allow user to configure output stream:
    //          ,            ,        socket,      ostream     。
    #ifndef BOOST_ASSERT_MSG_OSTREAM
    # define BOOST_ASSERT_MSG_OSTREAM std::cerr
    #endif

    namespace boost
    { 
      namespace assertion 
      { 
        namespace detail
        {
          //         ,  crash   。
          //        ,       crash   ,    ,        。
          inline void assertion_failed_msg(char const * expr, char const * msg, char const * function,
            char const * file, long line)
          {
            BOOST_ASSERT_MSG_OSTREAM
              << "***** Internal Program Error - assertion (" << expr << ") failed in "
              << function << ":
" << file << '(' << line << "): " << msg << std::endl; std::abort(); } } // detail } // assertion } // detail #endif #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ ? ((void)0) \ : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) #endif //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// #undef BOOST_VERIFY #if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) // ,expr 。 # define BOOST_VERIFY(expr) ((void)(expr)) #else # define BOOST_VERIFY(expr) BOOST_ASSERT(expr) #endif

실례:
우 리 는 클래스 에서 단언 을 정의 하고 그것 을 가짜 로 만 들 었 다.
#include <iostream>
#include <cstdlib>

#include <boost/assert.hpp>

using namespace std;

class Dummy
{
public:
    void foo()
    {
        const bool expr = false;
        
        BOOST_ASSERT(expr);
    }
};

int main(int argc, char** argv)
{
    Dummy dummy;
    dummy.foo();

    return 0;
}
boostsource: main.cpp:15: void Dummy::foo(): Assertion `expr' failed.

      (    1,     : 238  )
단언 이 실패 한 후에 오 류 는 main. cpp 의 15 번 째 줄 에 위치 하고 Dummy 류 에 속 하 는 foo () 함수 입 니 다.
다음은 저희 가 BOOST 를 사용 해 보도 록 하 겠 습 니 다.ASSERT_MSG
#include <iostream>
#include <cstdlib>

#include <boost/assert.hpp>

using namespace std;

class Dummy
{
public:
    void foo()
    {
        const bool expr = false;
        
        BOOST_ASSERT_MSG(expr, "Oops, XXX is invalid");
    }
};

int main(int argc, char** argv)
{
    Dummy dummy;
    dummy.foo();

    return 0;
}
***** Internal Program Error - assertion (expr) failed in void Dummy::foo():
main.cpp(15): Oops, XXX is invalid

      (    1,     : 355  )
이번에 우리 가 단언 이 가짜 라 는 것 을 보 았 을 때 시스템 은 우리 가 정의 한 오류 정 보 를 보 여 주 었 다.만약 우리 가 단언 한 사용자 정의 메시지 부분 에서 의미 있 는 정 보 를 제공 했다 면, 단언 이 가짜 일 때, 우 리 는 프로그램의 버그 를 신속하게 찾아내 서 디 버 깅 의 효율 을 현저히 높 일 수 있다.
다음은 사용자 정의 반전 함 수 를 설정 하여 단언 이 가짜 인 상황 을 처리 합 니 다.
#include <iostream>
#include <cstdlib>

#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>

using namespace std;

namespace boost
{
void assertion_failed_msg(char const * expr, char const * msg,
                            char const * function, char const * file, long line)
{
    std::cout << "Something to handle assert" << std::endl;
}
}
  
class Dummy
{
public:
    void foo()
    {
        const bool expr = false;
        
        BOOST_ASSERT_MSG(expr, "Oops, XXX is invalid");
    }
};

int main(int argc, char** argv)
{
    Dummy dummy;
    dummy.foo();

    return 0;
}
Something to handle assert

      (    1,     : 343  )
사용자 정의 리 셋 함 수 를 사용 합 니 다. 저 희 는 오류 정 보 를 로그 에 쓰 거나 GUI 를 사용 하여 오 류 를 표시 할 수 있 는 등 매우 큰 자 유 를 가지 고 있 습 니 다.
메모: 사용자 정의 리 셋 함 수 는 한 번 만 정의 할 수 있 습 니 다!
마지막 으로 하나 더 드 리 겠 습 니 다. assert 와 BOOST 를 동시에 사용 합 니 다.ASSERT_MSG 의 예 를 들 어, 내 가 어떻게 HACK 을 통 해 assert 에 사용자 정의 정 보 를 출력 하 는 지 볼 수 있 습 니 다.
#include <iostream>
#include <cstdlib>
#include <cassert>

//   BOOST_ASSERT,    std::assert
#define BOOST_DISABLE_ASSERTS
#include <boost/assert.hpp>

using namespace std;

class Dummy
{
public:
    void foo()
    {
        const bool expr = false;
        
        BOOST_ASSERT_MSG(expr, "Oops, XXX is invalid");
        assert(expr && "Haha... This is a hack");
    }
};

int main(int argc, char** argv)
{
    Dummy dummy;
    dummy.foo();

    return 0;
}
boostsource: main.cpp:19: void Dummy::foo(): Assertion `expr && "Haha... This is a hack"' failed.

      (    1,     : 224  )
이 예 에서 나 는 BOOSTASSERT_MSG 가 비활성화 되 었 습 니 다. 결 과 를 통 해 알 수 있 듯 이 이것 은 std: assert 의 기능 에 영향 을 주지 않 았 습 니 다.
별 출력 중
Assertion `expr && "Haha... This is a hack"
제 HACK 과정 입 니 다. BOOST 를 모 의 할 수 있 습 니 다.ASSERT_MSG 사용자 정의 메시지 의 부분 은 Boost 를 사용 하지 않 을 때 유용 합 니 다.
요약:
Boost 라 이브 러 리 의 단언 은 우리 에 게 매우 큰 유연성 을 제공 하고 std: assert 와 함께 사용 하면 효과 가 더욱 좋다.

좋은 웹페이지 즐겨찾기