DEBUG에서는 범위 검사를 수행하지만 RELEASE에서는 검사하지 않고 std::Vector의 Operator[] 컴파일을 만드는 방법

StackOverflow https://stackoverflow.com/questions/1290396

문제

저는 비주얼 스튜디오 2008을 사용하고 있습니다.

나는 std::Vector가 at() 함수를 사용하여 범위를 확인하고 [] 연산자를 잘못 사용하여(범위를 벗어난) 항목에 액세스하려고 하면 정의되지 않은 동작을 수행한다는 것을 알고 있습니다.

범위 검사를 사용하여 내 프로그램을 컴파일할 수 있는지 궁금합니다.이런 식으로 연산자[]는 at() 함수를 사용하고 무언가가 범위를 벗어날 때마다 std::out_of_range를 던집니다.

릴리스 모드는 연산자[]에 대한 경계 검사 없이 컴파일되므로 성능이 저하되지 않습니다.

Borland C++를 사용하여 작성된 앱을 Visual Studio로 마이그레이션하고 코드의 작은 부분에 다음이 포함되어 있기 때문에 이에 대해 생각하게 되었습니다(i=0, j=1).

v[i][j]; //v is a std::vector<std::vector<int> >

벡터 'v'의 크기는 [0][1]입니다(따라서 벡터의 요소 0에는 요소가 하나만 있습니다).이것은 정의되지 않은 동작입니다. 하지만 Borland는 여기서 0을 반환하고 VS는 충돌합니다.나는 0을 반환하는 것보다 충돌을 더 좋아하므로 std::out_of_range 예외가 발생하여 더 많은 '충돌'을 얻을 수 있다면 마이그레이션이 더 빨리 완료될 것입니다(그래서 Borland가 숨기고 있던 더 많은 버그가 노출될 것입니다).

도움이 되었습니까?

해결책

Visual Studio 2005 및 2008은 이미 경계 검사를 수행하고 있습니다. operator[] 기본적으로 둘 다 디버그 및 릴리스 빌드.

이 동작을 제어하는 ​​매크로는 다음과 같습니다. _SECURE_SCL.경계 검사를 비활성화하려면 0으로 설정합니다.

VS2010의 현재 계획은 릴리스 빌드에서는 기본적으로 경계 검사를 비활성화하고 디버그에서는 계속 유지하는 것입니다.(매크로 이름도 다음으로 변경되었습니다. _ITERATOR_DEBUG_LEVEL.아직 이에 대한 공식적인 문서가 있는지는 모르겠지만 언급된 바 있습니다. 여기 그리고 여기)

다른 팁

여기에서 논의 된 바와 같이 플래그 _glibcxx_debug가 STL 컨테이너에서 경계 확인을 수행 할 수 있도록하십시오.http://gcc.gnu.org/onlinedocs/libstdc+/manual/debug_mode.html

나는 이것을 너무 조기에 물었지만 어쨌든 답을 게시하여 지식을 공유하고 있습니다.

Visual Studio에서 구현 된 STL은 이미 디버그 모드에서 컴파일 할 때 확인을 수행합니다. 이것은에서 볼 수 있습니다 <vector> 헤더:

reference operator[](size_type _Pos)
        {   // subscript mutable sequence

 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));
        }

따라서 벡터 클래스에 대한 경계가 있습니다. 나는 다른 컨테이너를 보지 않았지만 동일한 메커니즘을 가지고 있다고 확신합니다.

지금은 Windows 머신에 액세스 할 수 없습니다. 그러나 Mac OS X 시스템에서 G ++로 전달 된 STL 구현을 살펴보면 /usr/include/c+/4.0.0/bits/stl_vector.h :

  // element access
  /**
   *  @brief  Subscript access to the data contained in the %vector.
   *  @param n The index of the element for which data should be
   *  accessed.
   *  @return  Read/write reference to data.
   *
   *  This operator allows for easy, array-style, data access.
   *  Note that data access with this operator is unchecked and
   *  out_of_range lookups are not defined. (For checked lookups
   *  see at().)
   */
  reference
  operator[](size_type __n)
  { return *(begin() + __n); }

수표가 수행되지 않고 디버그 모드에서 이벤트가 있습니다. 아니요 _glibcxx_debug marcro 가이 코드에서 확인됩니다.

MSVC와 함께 제공되는 자신의 STL 구현을 살펴보고 수행 한 작업을 확인하십시오. 어떠한 경우에도 수표가 없으면 ... 선택의 여지가 없지만 at () .. :-(

C ++는 벡터 연산자 []를 속도를 위해 예외를 던지지 않는 것으로 정의합니다.

주요 "숨겨진"버그가 사라질 것이라고 확신 할 때까지 디버그 구성의 응용 프로그램을 잠시 동안 테스트하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top