2017-04-14 3 views
1

내가 특별히 비주얼 스튜디오 내가 부호 INT/서명되지 않은 사용하고 일부 DSP 관련 업무에 대한 2015 업데이트 3C++의 차이 부호 INT 긴 부호 INT

비주얼 스튜디오 컴파일러로 Windows에서 C++ 개발을하고있는 중이 야 long 데이터 형식입니다. C/C++ 형식으로 빌드 된이 두 가지의 차이점은 무엇입니까?

Google과 SO를 통해 조금씩 검색하여 이러한 참조를 발견했습니다. 비주얼 스튜디오 GNU C/C++ (2015

  • Types documentationG++ compiler는 C/C++에서 동일한 기본 유형 구현을 사용하는 것이 명시된에 대한 cppreference.com
  • MSDN에
  • Types documentation

    1. Types documentation, 나는 여기에 C의 문서를 참조하십시오)

    나는 cppreference 문서가 ISO C++ 11 표준에 대한 요약이라고 가정합니다. 그래서에서 부호와는 INT는 LP/ILP 32/64 데이터 모델에 따라 16/32 비트 부호가 "표준"부호 길이와 긴 부호 INT LP에 따라 32/64 비트가/ILP 반면 32/64 데이터 모델.

    은 MSDN 및 GNU 문서에 대해서는 모든 필드는 부호 INT/부호없는 긴 32 비트를 사용하는 구현을 차감 한 금액 4,294,967,295까지의 값을 보유 할 수 있습니다. 그러나 GNU 문서는 또한 여러분의 시스템에 따라 unsigned long long이 64 비트가 될 수 있다고 말했습니다. 서명되지 않은 긴 64 비트에 대한

    1. 을, 천장 4,294,967,295 정의되지 않은 행동이나 올바른 행동을 넘어 가고 다음과 같이

      그래서 내 질문입니까?

    2. Visual Studio에서 컴파일 된 Windows 시스템에서 작동하는 응용 프로그램이있는 경우 basicall 부호가 없음 == 부호가없는 long입니다. 참인가 거짓인가? 내가 GNU 컴파일러에 의해 컴파일 된 응용 프로그램이 리눅스/윈도우에서 작업하는 경우
    3. 나는 부호없는 긴 == 부호 INT 또는 부호없는 긴 == 서명되지 않은 오래 오래 데이터 오버 플로우를 피하기 위해 여부를 확인해야합니다. 참 또는 거짓
    4. 이러한 Visual Studio/GNU/Clang/Intel 컴파일러로 컴파일 될 수있는 크로스 플랫폼 응용 프로그램이있는 경우 데이터가 넘치지 않도록 선 처리기를 여러 개 사용하여 환경을 명확하게 분류해야합니다. 맞음 또는 거짓

    미리 감사드립니다.

    편집 : @PeterRuderman에게 서명되지 않은 유형의 ceil 값을 초과하는 것은 정의되지 않은 동작임을 지적합니다.주변 포장 자체가 원인 천장 4,294,967,295 넘어 것, 부호없는 64 비트 길이의 경우

    1. :

      그럼 내 질문 1로 변경됩니다?

  • +0

    'unsigned int'와 'unsigned long'이 같은 범위와 표현을 가지더라도 여전히 고유 한 유형이라는 점에 유의하십시오. –

    답변

    1

    대답은 예, sizeof(unsigned)sizeof(unsigned long)과 같을 수는 없지만 MSVC에있는 것 같습니다. 플랫폼 독립적 인 방법으로 정수의 크기를 알아야 할 경우 <cstdint> : uint32_tuint64_t의 형식을 사용하십시오. 휴대 전화 코드에서 long을 피하십시오, 그것은 많은 두통으로 이어질 수 있습니다.

    부호없는 정수가 오버플로되는 것은 정의되지 않은 동작입니다. 정의 된 동작은 값이 랩 어라운드한다는 것입니다. (예 : std::numeric_limits<uint64_t>::max() + 43 == 42). 유형의 경우 오버플로가 정의되지 않은 동작 인 경우 사실이 아닙니다.

    마지막 질문에 답하기 위해 64 비트 정수는 [0,2 2 -1] 범위의 값을 저장할 수 있습니다. 2 +1은 랩 어라운드가 발생하지 않습니다.

    +0

    서명 된 오버플로가 바로 정의되지 않은 동작이 아닌 구현 정의입니다. 어쩌면 ** [expr] ** note 4가 여전히 호출하는 것 같습니다 N4594로 정의되지 않았습니다 – user4581301

    +0

    빠른 답변 감사드립니다. 이것과 관련된 또 다른 질문입니다. 라이브러리에이 좋은 데이터 유형이 모두있는 경우 왜 short, int, long 및 해당 부호없는 해당 유형이 필요합니까? 또는 다른 이유에서 short, int, long 및 해당 부호없는 해당 구현이 의 유형과 동일한 규칙을 따르지 않는 이유는 무엇입니까? – yc2986

    +2

    cstdint의 유형은 * 비교적 * 새로운 유형입니다. 위원회는 수많은 코드를 깨지 않으면 서 이전 형식을 제거 할 수 없었습니다. 그리고 성능상의 이유 때문에 컴파일러가 정수 크기를 선택하는 것이 더 나은 경우도 있습니다. –

    1

    C++ 표준에서 은 0에서 65535 사이의 값만 나타낼 수 있습니다. 실질적으로 이것은 16 비트에 해당합니다. 구현 (즉, 컴파일러)은 더 큰 범위의 unsigned int을 제공 할 수 있지만 필수는 아닙니다.

    이와 대조적으로, unsigned long int0에서 4294967295까지의 값을 나타낼 수 있습니다. 실제로 이것은 32 비트에 해당합니다. 다시 한 번 구현하면 더 큰 범위를 지원할 수 있습니다.

    이러한 유형의 범위와 크기는 구현에 따라 정의됩니다. 구현은 최소 요구 사항과 선택한 문서를 충족해야합니다.

    구현시 둘 다 32 비트 인 unsigned intunsigned long int을 제공하는 것이 일반적입니다. 또는 하나 또는 둘 다 64 비트가되도록하십시오. 앞서 언급 한 것처럼 Visual Studio 2015의 설명서에 과 unsigned long int은 모두 0에서 4294967295까지의 값을 나타냅니다.

    시스템 범위를 대상으로 할 수있는 g ++와 같은 컴파일러의 경우 선택 사항은 종종 대상 시스템에 의해 결정됩니다. 따라서 32 비트 시스템의 g ++ 빌드는 unsigned long의 다른 범위를 64 비트 시스템의 빌드보다 지원할 수 있습니다.

    천장 4,294,967,295 정의되지 않은 행동이나 올바른 행동을 넘어 가고, 서명되지 않은 긴 64 비트에 대한 질문

    에 대답하려면?

    예상되는 결과가 나오지 않더라도 잘 정의 된 동작입니다. C++의 부호없는 정수 타입은 모듈로 산술을 사용합니다. 0에서 4294967295 범위를 벗어나는 정수 값 (해당 범위를 지원할 수있는 형식)은 해당 범위에 있도록 변환됩니다 (수학적으로는 4294967296 [마지막 숫자 참고)]을 반복적으로 더하거나 뺍니다). 다른 말로하면, "랩 어라운드 (wrap around)"합니다.

    Visual Studio에서 컴파일 된 Windows 시스템에서 작동하는 응용 프로그램이있는 경우 basicall unsigned == unsigned long. 참인가 거짓인가?

    Visual Studio 2015를 사용한다고 가정하면 연결된 문서가 사실입니다. 향후 Microsoft 제품에 적용될 수도 있고 적용되지 않을 수도 있습니다 - 구현 결정입니다.

    나는 긴 부호없는 긴 부호없는 긴 == 부호 INT 또는 부호없는 긴 == 데이터 오버 플로우를 피하기 위해 여부를 확인해야합니다 리눅스/윈도우 작업 GNU 컴파일러에 의해 컴파일 된 응용 프로그램이있는 경우. 맞음 또는 틀림

    실제로는 false입니다.

    사실 인 가정에 의존하는 코드를 이식하는 경우에만 해당됩니다.

    사용할 수있는 기술이 있으므로 코드는 이러한 가정이 사실에 의존하지 않습니다. 예를 들어 두 개의 unsigned 값이 오버 플로우 또는 언더 플로우하는 작업을 안전하게 감지하고 필요한 결과를 생성하기위한 조치를 취할 수 있습니다. 모든 작업이 적절하게 검사되면 특정 유형의 유형에 의존하지 않아도됩니다.

    나는 명확하게 데이터 오버 플로우를 방지하기 처리기의 무리와 함께 환경을 분류해야이 비주얼 스튜디오/GNU/연타/인텔 컴파일러의 모든으로 컴파일 할 수있는 크로스 플랫폼 응용 프로그램이있는 경우. 맞음 또는 틀림

    사실은 아닙니다. 사실, 종종 사실입니다.

    표준 C++의 영역에 코드가 붙어있는 경우이를 방지하는 기술이 있습니다 (위에서 언급 한 것처럼 서명되지 않은 유형의 크기 의존성을 피할 수 있음).

    표준 C++ (예 : Windows API, C++ 표준에없는 posix 함수) 외부에있는 함수를 사용하거나 래퍼를 제공하는 코드 인 경우 종종 필요할 수 있습니다. 그러한 경우에도 그러한 일은 피할 수 있습니다. 예를 들어 posix를 사용하는 버전이 아닌 다른 소스에 Windows API를 사용하는 함수 버전을 배치하십시오. 빌드 프로세스 (makefile 등)를 구성하십시오. 예를 들어, Windows 용으로 빌드하는 경우에는 유닉스 버전에서 컴파일하거나 링크하지 마십시오.

    +0

    @Peter에 대한 자세한 답변을 보내 주셔서 감사합니다. "unsigned short int"는 0-65535 범위의 16 비트 데이터 형식을위한 것입니다. 'unsigned short','unsigned int','unsigned long'과'unsigned long long' 사이에 겹침이 왜 있는지 혼란스러워합니다. – yc2986

    +0

    오버랩은 역사적이며 C에서 상속됩니다.'short' 유형 ('signed' 및'unsigned')은 플랫폼이 지원하는 "작은"유형이었고 메모리를 절약하는 데 사용되었습니다. long 타입은 플랫폼이 지원할 long 타입이다. 'int '타입은 (예를 들어 하드웨어에 구현 된 레지스터와 연산을 가진) "원시"타입이었고, 실제적으로 어떤 머신에서는'short', 다른 머신에서는'long'과 동등했습니다. 나중에 더 많은 하드웨어가 기본적으로 32 비트 유형을 지원 했으므로'int'와'long'이 동등한 것이 더 일반적이되었습니다. 그런 다음 64 비트에 대한 하드웨어 지원이 제공되었으며 'long long'유형은 – Peter

    +0

    으로 태어났습니다 (예 : 정수 유형에서 홀수 개의 비트와 함께 작동하는 기계 및 컴파일러가 있음). 그러나 16에서 32 비트에서 64 비트의 관점에서 유형과 그 중첩의 이유가 그 종류입니다. – Peter

    관련 문제