strtol의 결과를 int에 캐스트해야합니까?
문제
다음 코드는 G ++ 4.1.1과 함께 경고하지 않습니다. -Wall
.
int octalStrToInt(const std::string& s)
{
return strtol(s.c_str(), 0, 8);
}
strtol이 반환하기 때문에 경고를 기대하고있었습니다 long int
그러나 내 기능은 평원 만 반환하는 것입니다 int
. 다른 컴파일러가 여기서 경고를 방출 할 수 있습니까? 이 경우 int에 반환 값을 int에 시전해야합니까?
해결책
이러한 경고를 켜려면 -wconversion 플래그가 필요할 수 있습니다. 그러나 경고하지 않을 것입니다 긴 -> int, 그것들은 GCC와 동일한 크기이기 때문에 (변환으로 인해 값은 변하지 않음). 그러나 예를 들어 변환하면 긴 -> 짧은
나는 단순히 캐스트를하는 것이 권장되지 않을 것이라고 생각합니다. 그것은 단지 버그의 가능성을 덮을 것이기 때문입니다. 그러한 캐스트가 컴파일러를 달래기 위해 값을 수정하지 않는지 확인한 후에는 괜찮을 것입니다.
다른 팁
최고의 접근 방식은 다음과 같습니다.
long x = strtol(...); assert(x <= INT_MAX); return (int)x;
당신은 필요합니다 limits.h
그리고 assert.h
액세스 할 수없는 경우 boost::numeric_cast
, 당신은 간단한 모방을 쓸 수 있습니다.
template <typename T, typename S>
T range_check(const S &s) {
assert(s <= std::numeric_limits<T>::max());
assert(s >= std::numeric_limits<T>::min());
return static_cast<T>(s); // explicit conversion, no warnings.
}
return range_check<int>(strtol(some_value,0,8));
실제로 부동 소수점 대상 유형에 효과가 없기 때문에 약간의 치트입니다. min()
정수 유형과 동일하지 않으므로 +/-에 대해 확인해야합니다. max()
. 독자를위한 운동.
ASSERT를 사용하든 다른 오류 처리 여부는 유효하지 않은 입력에 대해 실제로하고 싶은 일에 달려 있습니다.
또한 있습니다 boost::lexical_cast
(Off-Hand 나는 그것을 읽는 방법을 모른다)와 StringStream. C 라이브러리 기능이있는 유형이 아니라 원하는 유형을 읽으십시오.
플랫폼의 "int"및 "long int"데이터 유형의 크기와 범위가 같기 때문에 여기에는 경고가 표시되지 않습니다. 건축에 따라 다르게 될 수 있습니다.
이상한 오류로부터 자신을 보호하려면 범위 점검을 사용하십시오. std :: numeric_limits :: min/max (참조)를 사용하는 것이 좋습니다.
범위 확인 후 STATIC_CAST 또는 C 스타일 캐스트를 안전하게 사용할 수 있습니다.
반면에 std :: stringstream 클래스에서 구현 된 동일한 기능에 의존 할 수 있습니다. STD :: StringStream으로의 변환은 기본적으로 플랫폼 안전 및 유형 안전입니다.
대부분의 최신 컴파일러는 구성 한 경고 수준에 따라 변환 및 가능한 자리에 대해 경고합니다. 경고 레벨 4 인 MSVC에서.
모범 사례는 기능에서 오랫동안 반환하고 호출 코드가 변환을 처리하는 방법을 결정하게하는 것입니다. let_me_be가 제안한대로, strtol에서 돌아 오는 값이 반환하기 전에 int에 맞는지 확인하십시오.