다음을 통해 공유


SafeInt 클래스

정수 오버플로를 방지할 수 있도록 정수 기본 형식을 확장하고 다양한 형식의 정수 비교를 허용합니다.

참고 항목

SafeInt 라이브러리의 최신 버전은 .에 https://github.com/dcleblanc/SafeInt있습니다. SafeInt 라이브러리를 사용하려면 리포지토리를 복제하고 #include "SafeInt.hpp"

구문

template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>
class SafeInt;

매개 변수

T
SafeInt로 대체되는 정수 또는 부울 매개 변수의 형식입니다.

E
오류 처리 정책을 정의하는 열거형 데이터 형식입니다.

U
보조 피연산자에 대한 정수 또는 부울 매개 변수의 형식입니다.

rhs
[in] 여러 독립 실행형 함수에서 연산자의 오른쪽에 있는 값을 나타내는 입력 매개 변수입니다.

i
[in] 여러 독립 실행형 함수에서 연산자의 오른쪽에 있는 값을 나타내는 입력 매개 변수입니다.

bits
[in] 여러 독립 실행형 함수에서 연산자의 오른쪽에 있는 값을 나타내는 입력 매개 변수입니다.

멤버

공용 생성자

속성 설명
SafeInt::SafeInt 기본 생성자입니다.

할당 연산자

속성 구문
= template<typename U>
SafeInt<T,E>& operator= (const U& rhs)
= SafeInt<T,E>& operator= (const T& rhs) throw()
= template<typename U>
SafeInt<T,E>& operator= (const SafeInt<U, E>& rhs)
= SafeInt<T,E>& operator= (const SafeInt<T,E>& rhs) throw()

캐스팅 연산자

속성 구문
bool operator bool() throw()
char operator char() const
signed char operator signed char() const
unsigned char operator unsigned char() const
__int16 operator __int16() const
unsigned __int16 operator unsigned __int16() const
__int32 operator __int32() const
unsigned __int32 operator unsigned __int32() const
long operator long() const
unsigned long operator unsigned long() const
__int64 operator __int64() const
unsigned __int64 operator unsigned __int64() const
wchar_t operator wchar_t() const

비교 연산자

속성 구문
< template<typename U>

bool operator< (U rhs) const throw()
< bool operator< (SafeInt<T,E> rhs) const throw()
>= template<typename U>

bool operator>= (U rhs) const throw()
>= Bool operator>= (SafeInt<T,E> rhs) const throw()
> template<typename U>

bool operator> (U rhs) const throw()
> Bool operator> (SafeInt<T,E> rhs) const throw()
<= template<typename U>

bool operator<= (U rhs) const throw()
<= bool operator<= (SafeInt<T,E> rhs) const throw()
== template<typename U>

bool operator== (U rhs) const throw()
== bool operator== (bool rhs) const throw()
== bool operator== (SafeInt<T,E> rhs) const throw()
!= template<typename U>

bool operator!= (U rhs) const throw()
!= bool operator!= (bool b) const throw()
!= bool operator!= (SafeInt<T,E> rhs) const throw()

산술 연산자

속성 구문
+ const SafeInt<T,E>& operator+ () const throw()
- SafeInt<T,E> operator- () const
++ SafeInt<T,E>& operator++ ()
-- SafeInt<T,E>& operator-- ()
% template<typename U>

SafeInt<T,E> operator% (U rhs) const
% SafeInt<T,E> operator% (SafeInt<T,E> rhs) const
%= template<typename U>

SafeInt<T,E>& operator%= (U rhs)
%= template<typename U>

SafeInt<T,E>& operator%= (SafeInt<U, E> rhs)
* template<typename U>

SafeInt<T,E> operator* (U rhs) const
* SafeInt<T,E> operator* (SafeInt<T,E> rhs) const
*= SafeInt<T,E>& operator*= (SafeInt<T,E> rhs)
*= template<typename U>

SafeInt<T,E>& operator*= (U rhs)
*= template<typename U>

SafeInt<T,E>& operator*= (SafeInt<U, E> rhs)
/ template<typename U>

SafeInt<T,E> operator/ (U rhs) const
/ SafeInt<T,E> operator/ (SafeInt<T,E> rhs ) const
/= SafeInt<T,E>& operator/= (SafeInt<T,E> i)
/= template<typename U>

SafeInt<T,E>& operator/= (U i)
/= template<typename U>

SafeInt<T,E>& operator/= (SafeInt<U, E> i)
+ SafeInt<T,E> operator+ (SafeInt<T,E> rhs) const
+ template<typename U>

SafeInt<T,E> operator+ (U rhs) const
+= SafeInt<T,E>& operator+= (SafeInt<T,E> rhs)
+= template<typename U>

SafeInt<T,E>& operator+= (U rhs)
+= template<typename U>

SafeInt<T,E>& operator+= (SafeInt<U, E> rhs)
- template<typename U>

SafeInt<T,E> operator- (U rhs) const
- SafeInt<T,E> operator- (SafeInt<T,E> rhs) const
-= SafeInt<T,E>& operator-= (SafeInt<T,E> rhs)
-= template<typename U>

SafeInt<T,E>& operator-= (U rhs)
-= template<typename U>

SafeInt<T,E>& operator-= (SafeInt<U, E> rhs)

논리 연산자

속성 구문
! bool operator !() const throw()
~ SafeInt<T,E> operator~ () const throw()
<< template<typename U>

SafeInt<T,E> operator<< (U bits) const throw()
<< template<typename U>

SafeInt<T,E> operator<< (SafeInt<U, E> bits) const throw()
<<= template<typename U>

SafeInt<T,E>& operator<<= (U bits) throw()
<<= template<typename U>

SafeInt<T,E>& operator<<= (SafeInt<U, E> bits) throw()
>> template<typename U>

SafeInt<T,E> operator>> (U bits) const throw()
>> template<typename U>

SafeInt<T,E> operator>> (SafeInt<U, E> bits) const throw()
>>= template<typename U>

SafeInt<T,E>& operator>>= (U bits) throw()
>>= template<typename U>

SafeInt<T,E>& operator>>= (SafeInt<U, E> bits) throw()
& SafeInt<T,E> operator& (SafeInt<T,E> rhs) const throw()
& template<typename U>

SafeInt<T,E> operator& (U rhs) const throw()
&= SafeInt<T,E>& operator&= (SafeInt<T,E> rhs) throw()
&= template<typename U>

SafeInt<T,E>& operator&= (U rhs) throw()
&= template<typename U>

SafeInt<T,E>& operator&= (SafeInt<U, E> rhs) throw()
^ SafeInt<T,E> operator^ (SafeInt<T,E> rhs) const throw()
^ template<typename U>

SafeInt<T,E> operator^ (U rhs) const throw()
^= SafeInt<T,E>& operator^= (SafeInt<T,E> rhs) throw()
^= template<typename U>

SafeInt<T,E>& operator^= (U rhs) throw()
^= template<typename U>

SafeInt<T,E>& operator^= (SafeInt<U, E> rhs) throw()
| SafeInt<T,E> operator| (SafeInt<T,E> rhs) const throw()
| template<typename U>

SafeInt<T,E> operator| (U rhs) const throw()
|= SafeInt<T,E>& operator|= (SafeInt<T,E> rhs) throw()
|= template<typename U>

SafeInt<T,E>& operator|= (U rhs) throw()
|= template<typename U>

SafeInt<T,E>& operator|= (SafeInt<U, E> rhs) throw()

설명

SafeInt 클래스는 수학 연산에서 정수 오버플로를 방지합니다. 예를 들어 두 개의 8비트 정수를 더한다고 가정합니다. 첫 번째 정수의 값은 200이고, 두 번째 정수의 값은 100입니다. 올바른 수학 연산은 200 + 100 = 300입니다. 그러나 8비트 정수 제한으로 인해 상위 비트는 손실되고, 컴파일러에서 44(300 - 28)가 결과로 반환됩니다. 이 수학 수식을 사용하는 모든 연산에서 예기치 않은 동작이 생성됩니다.

SafeInt 클래스는 산술 오버플로가 발생하는지 여부 또는 코드에서 0으로 나누기를 시도하는지 여부를 확인합니다. 두 경우 모두, 클래스에서 오류 처리기를 호출하여 잠재적인 문제를 프로그램에 경고합니다.

이 클래스를 사용하여 SafeInt 개체인 서로 다른 두 형식의 정수를 비교할 수도 있습니다. 일반적으로 비교를 수행할 때는 먼저 숫자를 동일한 형식으로 변환해야 합니다. 한 숫자를 다른 형식으로 캐스팅할 때 데이터 손실이 없는지 확인해야 하는 경우도 많습니다.

이 항목의 연산자 표에는 SafeInt 클래스에서 지원하는 수학 연산자와 비교 연산자가 나와 있습니다. 대부분의 수학 연산자는 T 형식의 SafeInt 개체를 반환합니다.

SafeInt와 정수 형식 간의 비교 작업은 양쪽으로 모두 수행할 수 있습니다. 예를 들어 SafeInt<int>(x) < yy> SafeInt<int>(x)는 둘 다 유효하며 동일한 결과를 반환합니다.

많은 이진 연산자는 두 가지 SafeInt 형식을 사용할 수 없습니다. 이러한 예로 & 연산자가 있습니다. SafeInt<T, E> & int 는 지원되지만 SafeInt<T, E> & SafeInt<U, E> 지원되지 않습니다. 두 번째 식의 경우 컴파일러에서 반환할 매개 변수 형식을 알 수 없습니다. 이 문제에 대한 한 가지 솔루션은 두 번째 매개 변수를 기본 형식으로 다시 캐스팅하는 것입니다. 이 작업은 같은 매개 변수를 사용하여 SafeInt<T, E> & (U)SafeInt<U, E>로 수행할 수 있습니다.

참고 항목

비트 연산의 경우 서로 다른 두 매개 변수가 동일한 크기여야 합니다. 크기가 다르면, 컴파일러에서 ASSERT 예외가 throw됩니다. 이 작업의 결과는 정확하지 않을 수 있습니다. 이 문제를 해결하려면 더 큰 매개 변수와 크기가 같을 때까지 더 작은 매개 변수를 캐스팅합니다.

시프트 연산자의 경우 템플릿 형식의 비트보다 많은 비트를 이동하면 ASSERT 예외가 throw됩니다. 릴리스 모드에서는 아무 변화도 없습니다. 반환 형식이 원래 형식과 같은 시프트 연산자의 경우 두 형식의 SafeInt 매개 변수를 함께 사용할 수 있습니다. 연산자의 오른쪽에 있는 숫자는 이동할 비트 수만 나타냅니다.

SafeInt 개체와 논리적 비교를 수행하는 경우 비교는 엄격하게 산술입니다. 예를 들어 다음 식이 있다고 가정합니다.

  • SafeInt<uint>((uint)~0) > -1

  • ((uint)~0) > -1

첫 번째 문은 로 true확인되지만 두 번째 문은 .로 false확인됩니다. 0의 비트 부정 연산은 0xFFFFFFFF입니다. 두 번째 문에서 기본 비교 연산자는 0xFFFFFFFF와 0xFFFFFFFF를 비교하고 두 값이 같다고 간주합니다. SafeInt 클래스의 비교 연산자는 첫 번째 매개 변수는 부호가 없지만 두 번째 매개 변수는 음수임을 인식합니다. 따라서 비트 표현은 동일하지만, SafeInt 논리 연산자에서 부호 없는 정수가 -1보다 크다고 인식합니다.

SafeInt 클래스와 ?: 3개로 구성된 연산자를 함께 사용할 때는 주의하세요. 다음 코드 줄이 있다고 가정합니다.

Int x = flag ? SafeInt<unsigned int>(y) : -1;

컴파일러에서 이 코드를 다음과 같이 변환합니다.

Int x = flag ? SafeInt<unsigned int>(y) : SafeInt<unsigned int>(-1);

flagfalse이면, 컴파일러는 x에 값 -1을 할당하는 대신 예외를 throw합니다. 따라서 이 동작을 방지하려면 다음과 같은 올바른 코드 줄을 사용해야 합니다.

Int x = flag ? (int) SafeInt<unsigned int>(y) : -1;

TU에 부울 형식, 문자 형식 또는 정수 형식을 할당할 수 있습니다. 정수 형식은 부호 있는 형식이나 부호 없는 형식으로, 8비트에서 64비트의 임의 크기일 수 있습니다.

참고 항목

SafeInt 클래스는 모든 종류의 정수를 허용하지만, 부호 없는 형식에서 성능이 향상됩니다.

ESafeInt에서 사용하는 오류 처리 메커니즘입니다. SafeInt 라이브러리와 함께 두 가지 오류 처리 메커니즘이 제공됩니다. 기본 정책은 SafeIntErrorPolicy_SafeIntException으로, 오류가 발생하면 SafeIntException 클래스 예외가 throw됩니다. 다른 정책은 SafeIntErrorPolicy_InvalidParameter로, 오류가 발생하면 프로그램을 중지합니다.

오류 정책을 사용자 지정하는 두 가지 옵션이 있습니다. 첫 번째 옵션은 SafeInt를 만들 때 E 매개 변수를 설정하는 것입니다. 하나의 SafeInt에 대해서만 오류 처리 정책을 변경하려는 경우 이 옵션을 사용합니다. 다른 옵션은 SafeInt 라이브러리를 포함하기 전에 _SAFEINT_DEFAULT_ERROR_POLICY를 사용자 지정 오류 처리 클래스로 정의하는 것입니다. 코드의 모든 SafeInt 클래스 인스턴스에 대해 기본 오류 처리 정책을 변경하려는 경우 이 옵션을 사용합니다.

참고 항목

SafeInt 라이브러리에서 오류를 처리하는 사용자 지정 클래스는 오류 처리기를 호출한 코드에 제어를 반환하면 안 됩니다. 오류 처리기가 호출되면 작업의 결과를 SafeInt 신뢰할 수 없습니다.

상속 계층 구조

SafeInt

요구 사항

헤더: SafeInt.hpp

참고 항목

이 라이브러리의 최신 버전은 https://github.com/dcleblanc/SafeInt에 있습니다. 라이브러리를 복제하고 SafeInt.hpp를 포함하여 SafeInt 라이브러리를 사용합니다. safeint.h>에 이 GitHub 리포지토리를 <선호합니다. 적은 수의 버그 수정을 포함하고, C++의 <최신 기능을 사용하여 보다 효율적인 코드를 생성하며, gcc, clang 또는 Intel 컴파일러를 사용하여 모든 플랫폼에 이식 가능한 safeint.h> 의 최신 버전입니다.

예시

#include "SafeInt.hpp" // set path to your clone of the SafeInt GitHub repo (https://github.com/dcleblanc/SafeInt)

int main()
{
    int divisor = 3;
    int dividend = 6;
    int result;

    bool success = SafeDivide(dividend, divisor, result); // result = 2
    success = SafeDivide(dividend, 0, result); // expect fail. result isn't modified.
}

네임스페이스: 없음

SafeInt::SafeInt

SafeInt 개체를 생성합니다.

SafeInt() throw

SafeInt (const T& i) throw ()

SafeInt (bool b) throw ()

template <typename U>
SafeInt (const SafeInt <U, E>& u)

I template <typename U>
SafeInt (const U& i)

매개 변수

i
[in] 새로운 SafeInt 개체의 값입니다. 생성자에 따라 T 또는 U 형식의 매개 변수여야 합니다.

b
[in] 새로운 SafeInt 개체의 부울 값입니다.

u
[in] U 형식의 SafeInt입니다. 새로운 SafeInt 개체는 u와 동일한 값을 갖지만 T 형식입니다.

U 에 저장된 데이터의 형식입니다 SafeInt. 부울, 문자 또는 정수 형식일 수 있습니다. 정수 형식인 경우 부호 있거나 부호 없는 형식이며 8비트에서 64비트 사이일 수 있습니다.

설명

생성자 i 또는 u의 입력 매개 변수는 부울, 문자 또는 정수 형식이어야 합니다. 다른 유형의 매개 변수인 경우 클래스는 SafeInt 잘못된 입력 매개 변수를 나타내기 위해 static_assert 호출합니다.

템플릿 형식 U를 사용하는 생성자는 입력 매개 변수를 T에 지정된 형식으로 자동 변환합니다. SafeInt 클래스에서 데이터 손실 없이 데이터를 변환합니다. 데이터 손실 없이 데이터를 형식 T 으로 변환할 수 없는 경우 오류 처리기에 E 보고합니다.

부울 매개 변수에서 SafeInt를 만드는 경우 값을 즉시 초기화해야 합니다. 코드를 SafeInt<bool> sb;사용하여 생성할 SafeInt 수 없습니다. 이렇게 하면 컴파일 오류가 생성됩니다.