2017-01-15 11 views
2

numeric_limits<T>::max()이 최대 값이 아닌 0을 반환하는 명백한 버그를 해결하는 가장 좋은 방법을 찾으려고합니다.Apple Clang 및 numeric_limits <부호없는 __int128> :: max()는 0입니까?

첫째, 테스트 프로그램 :

$ cat test.cxx 
#include <iostream> 
#include <limits> 

int main(int argc, char* argv[]) 
{ 
#if (__SIZEOF_INT128__ >= 16) 
    std::cout << "__int128 is available" << std::endl; 
#else 
    std::cout << "__int128 is not available" << std::endl; 
#endif 

    unsigned __int128 m = std::numeric_limits<unsigned __int128>::max(); 
    if (m == 0) 
     std::cout << "numeric_limits<unsigned __int128>::max() is 0" << std::endl; 
    else 
     std::cout << "numeric_limits<unsigned __int128>::max() is not 0" << std::endl; 

    return 0; 
} 

__SIZEOF_INT128__ >= 16 시험은 128-bit integer - nonsensical documentation?에서 GCC 메일 링리스트에 대한 토론에서왔다.

그리고 결과 : 애플은 또한 플랫폼 및 도구, 그래서 버그 리포트는 문제가 해결되지 않습니다를 포기했다
$ c++ -Wall test.cxx -o test.exe 
$ ./test.exe 
__int128 is available 
numeric_limits<unsigned __int128>::max() is 0 

.

어떻게 해결할 수 있습니까?


진행 방법이 확실하지 않습니다. 위의 최소 예제와는 달리 코드에서 문제를 해결하려면 std 네임 스페이스의 함수를 재정의해야합니다. 하지만 overriding a function in std is not allowed. 코드에서

template<class T1, class T2> 
T1 Add(const T1& t1, const T2& t2) 
{ 
    if (std::numeric_limits<T1>::max() - t2 > t1) 
     throw std::runtime_error("overflow"); 

    return t1 + t2; 
} 

위, 우리가 T1 = __int128T2 상상할 수있는 모든 조합에 대한 전체 전문화를 제공해야합니다 :

다음은 실제 코드에서의 문제가 이유의 예입니다. 그게 현실적이지 않아.


문제가있는 컴퓨터의 컴파일러 버전 :

$ c++ --version 
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) 
Target: x86_64-apple-darwin13.4.0 
Thread model: posix 

그러나, 비 애플의 테스트 시스템에 이상 점프가 예상 낸다 결과 :

$ clang++-3.5 --version 
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 

$ clang++-3.5 -Wall test.cxx -o test.exe 

$ ./test.exe 
__int128 is available 
numeric_limits<unsigned __int128>::max() is not 0 
+1

더 새롭게 시도하십시오. 'Apple LLVM 버전 8.0.0 (clang-800.0.42.1)'에서 문제를 재현 할 수 없습니다. 제 생각 엔 clang의 이전 버전에서는''__libcpp_numeric_limits' (https://github.com/llvm-mirror)의 기본 구현을 얻었 기 때문에'std :: is_arithmetic <__int128> :: value'은'false'입니다./libcxx/blob/master/include/limits)'min' /'max'/등을 위해 제로를 산출합니다. 또한,'t2'가 음수이면 (그리고 형식이 서명 된 경우) 오버플로 감지가 UB라고 생각합니다. – Cornstalks

+1

'numeric_limits'를 사용하기 전에'is_specialized'를 체크해야합니다 ... –

+0

@Cornstalks - 고마워요. Xcode 6.0이 적용된 OS X 10.9의 Apple Clang 버전이 수정되었습니다. 내가 아는 한, 다른 버전은 없습니다 (사용자를 설치하거나 처음부터 새로 만들지는 않습니다).'Add' 예제는 강력한 전문이 아닌 완전한 전문 분야의 문제를 보여주기위한 것입니다. – jww

답변

1

쓰기 notstd::numeric_limits<T>:std::numeric_limits<T>

버그가있는 T의 경우에는 static max() (및 그 밖의 모든 것)에 올바른 동작을 오버로드하십시오.

notstd::numeric_limitsAdd에 사용하십시오.

또는 최신 컴파일러 및/또는 표준 라이브러리를 사용하십시오.

+0

감사합니다. Yakk. 우리는 비슷한 해결책을 찾고있었습니다. 테스트 해보고 다시보고하겠습니다. – jww