고정 너비 정수가 정의되어 있는지 확인하는 방법


25

C ++에서 고정 너비 정수는 optional 으로 정의되어 있지만 실제로 정의되어 있는지 확인하는 권장 방법을 찾지 못하는 것 같습니다.

고정 너비 정수를 사용할 수 있는지 확인하는 이식 가능한 방법은 무엇입니까?


이 될 것 같지 않습니다 기능 테스트 매크로 ,하지만 난 당신이 할 수 있다고 생각#if defined(INT8_MIN)
Zereges

2
std 라이브러리가 해당 기능 테스트 매크로를 제공하지 않으면 사용하는 툴체인이이를 제공하는지 또는 자체 테스트를 정의 할 수 있는지 확인할 수 있습니다. 예를 들어 CMake를 사용하면 정의 된 cpp파일 을 컴파일 하여 컴파일이 실패하는지 여부에 따라 정의 할 수있는 매크로가 설정되어 있는지에 따라 특정 언어 기능을 테스트 할 수 있습니다.
t.niese

cconf보다 autoconf를 선호한다면 미리 정의 된 테스트가 있습니다. AC_TYPE_INT8_T

stdint에 태그 점수가있는 사람은 IMO cstdint 를 동의어 ( stackoverflow.com/tags/stdint/synonyms ) 로 지정해야합니다 . 이 모호한 부분에 대해 별도의 C 및 C ++ 태그가 필요하지 않다고 생각합니다. 질문의 주요 태그로 충분합니다.
Peter Cordes

1
@PeterCordes 이번에는 효과가있었습니다 : stackoverflow.com/tags/stdint/synonyms
Andrew Henle

답변:


16

고정 너비 정수 유형이 제공되는지 판별하기 위해 해당 매크로 [U]INT*_MAX또는 [U]INT*_MIN매크로가 정의되어 있는지 확인할 수 있습니다 .

// may be necessary for your C++ implementation
#define __STDC_LIMIT_MACROS 
#include <cstdint>

#ifdef INT32_MAX
// int32_t must be available to get here
int32_t some32bitIntVariable;
#endif

7.20 정수 유형<stdint.h> 의 C11 표준의 제 4 항 (굵게 표시된 부분을 참고)

구현에서 제공하는 여기에 설명 된 각 유형에 대해 <stdint.h>해당 typedef이름을 선언 하고 관련 매크로를 정의해야합니다 . 반대로, 구현에서 제공하지 않는 여기에 설명 된 각 유형에 대해 <stdint.h>해당 typedef이름을 선언 하거나 연관된 매크로를 정의하지 않아야합니다 .

C ++는를 통해 C 구현을 상속합니다 <cstdint>. 자세한 내용은 <cstdint>vs<stdint.h> 를 참조 하십시오. 또한 무엇 __STDC_LIMIT_MACROS__STDC_CONSTANT_MACROS의미합니까? 에 대한 자세한 내용 __STDC_LIMIT_MACROS.

따라서,이 경우에 int32_t사용할 수 있으며, INT32_MAX그리고 INT32_MIN있어야 #defineD '. 반대로, int32_t사용할 수없는 경우 'd' INT32_MAXINT32_MIN허용 되지 않습니다 #define.

참고하지만, @NicolBolas는 다른 답변에 명시된 바와 같이 실제로 확인하기 위해, 필요하지 않을 수도있다.


확인하기 위해 짧아 질 것 [U]INT*_C대신에 최소 및 최대 매크로
phuclv

1
@phuclv 그건 똑같지 않다. 예를 들어,이 INT64_C경우 정의 int64_least_t하지 않을 경우 사용할 수 있습니다 int64_t사용할 수 있습니다. 참조 문서
궤도의 밝기 경주를

19

광범위하게 말하면 ... 당신은하지 않습니다.

고정 크기 정수 유형을 사용해야하는 경우 해당 유형의 특정 크기 를 명시 적으로 필요로 합니다. 즉, 해당 크기의 정수를 얻을 수 없으면 코드가 작동하지 않습니다. 따라서 당신은 그것들을 사용해야합니다. 누군가가 위의 유형이없는 컴파일러에서 코드를 사용하면 코드가 컴파일되지 않습니다. 컴파일하면 코드가 작동하지 않았기 때문에 괜찮습니다.

실제로 고정 크기 정수 가 필요 하지 않지만 다른 이유로 단순히 정수를 원하면 int_least_*유형 을 사용하십시오 . 구현이 정확히 그 크기를 줄 수 있다면, least_*타입은 그 크기를 가질 것입니다.


4
사실이 아닙니다. 전에 uint8_t를 지원하지 않는 플랫폼에 대해 operator = / etc를 구현하는 스텁 패스 스루를 작성했습니다. 그러나 효율성과 디버깅 목적으로 실제로 필요하지 않은 경우 패스 스루를 사용하고 싶지 않습니다.
TLW

@TLW : " 이전에 uint8_t를 지원하지 않는 플랫폼에 대해 operator = / etc를 구현하는 스텁 패스 스루를 작성했습니다. "그래, 왜? 어떤 코드를 작성 했습니까? 바이트는 8 비트 (아마도 당신이 사용하고있는 이유 uint8_t)인지 확인해야하지만이 코드는 바이트가 8 비트가 아닌 플랫폼에서 실행되어야했습니다 ( 오래된 C ++ 구현, 왜 uint8_t사용할 수없는 유일한 이유 입니까?) 즉, 이전 버전과의 호환성을 벗어난 이유는 무엇입니까?
Nicol Bolas

독점적이므로 너무 말할 수 없습니다. 무엇보다 기발한 하드웨어 스택을 지원해야하는 공유 코드베이스. uint8_t이었다 훨씬 이전 임시 (그리고 자주 고장) 방식에 비해 선명.
TLW

예를 들어 8 비트 바이트로 표현되는 알고리즘이있는 경우 패스 쓰루는 한 번만 쓸 수 있으며 테스트하기 쉽습니다. 모든 장소를 고치는 것은 임시적이고 미묘하게 잘못되기 쉽습니다. 노력 O(1)O(n). 사람들이 예를 들어 같은 이유 uint16_t. 당신은 "uint32_t를 사용하지 않고 스스로 캐스팅하지 않겠습니까?"라고 묻습니다.
TLW

@TLW : " uint16_t와 같이 사람들이 사용하는 것과 같은 이유입니다. "이것이 제가 사용하는 이유는 아닙니다 uint16_t. 내 이유는 내 컴퓨터에 엔디안을 사용하여 부호없는 정수 이진 형식으로 16 비트의 데이터를 정확하게 얻을 것으로 예상되는 장치 / 형식 / 등과 통신하고 있으며 정확히 말하면 효과적으로 의사 소통하는 것이 훨씬 더 어렵습니다. 내 프로그램 (그리고 내가 사용하는 API)은 기본적으로 그것을 제공하지 않는 컴퓨터에서 작동 할 수 없습니다 .
니콜 올가미
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.