c++ - unsigned size_t




size_t에 지정된 음수를 찾는 방법은 무엇입니까? (2)

이 선언은 g ++에서 경고없이 컴파일됩니다. -pedantic -Wall (버전 4.6.3) :

std::size_t foo = -42;

덜 눈에 띄지 않는 가짜는 size_t 인자를 가진 함수를 선언하고 그것을 음수 값으로 호출하는 것입니다. 그러한 기능이 부주의 한 부정적인 논증 (44.7 / 2에 복종하는 굉장한 quintillion으로 나타남)으로부터 보호 할 수 있습니까?

불완전한 답변 :

size_t를 (signed) long으로 변경하면 의미와 size_t의 다른 이점을 무시합니다.

이것을 ssize_t로 바꾸는 것은 Standard가 아닌 POSIX 일뿐입니다.

그것을 ptrdiff_t로 변경하면 부서지기 쉽고 때로는 손상됩니다.

큰 값 (상위 비트 세트 등)에 대한 테스트는 임의적입니다.


다음 발췌문은 사립 도서관에서 발췌 한 것입니다.

#include <limits.h>

#if __STDC__ == 1 && __STDC_VERSION__ >= 199901L || \
    defined __GNUC__ || defined _MSC_VER
    /* Has long long. */
    #ifdef __GNUC__
        #define CORE_1ULL __extension__ 1ULL
    #else
        #define CORE_1ULL 1ULL
    #endif
    #define CORE_IS_POS(x) ((x) && ((x) & CORE_1ULL << (sizeof (x)*CHAR_BIT - 1)) == 0)
    #define CORE_IS_NEG(x) (((x) & CORE_1ULL << (sizeof (x)*CHAR_BIT - 1)) != 0)
#else
    #define CORE_IS_POS(x) ((x) && ((x) & 1UL << (sizeof (x)*CHAR_BIT - 1)) == 0)
    #define CORE_IS_NEG(x) (((x) & 1UL << (sizeof (x)*CHAR_BIT - 1)) != 0)
#endif

#define CORE_IS_ZPOS(x) (!(x) || CORE_IS_POS(x))
#define CORE_IS_ZNEG(x) (!(x) || CORE_IS_NEG(x))

이것은 모든 부호없는 유형에 적용됩니다.


이것에 대한 경고를 내리는 문제는 표준에 따라 정의되지 않은 동작이 아니라는 것입니다. 서명 된 값을 동일한 크기의 부호없는 유형으로 변환하면 나중에 해당 값을 부호있는 값으로 변환하고 표준 호환 컴파일러에서 원래 값을 가져올 수 있습니다.

또한, size_t로 변환 된 음수 값을 사용하면 다양한 오류 조건에서 매우 일반적으로 사용됩니다. 많은 시스템 호출은 성공을 위해 unsigned ( size_t 또는 off_t ) 값을 반환하고 오류는 -1 (unsigned)으로 변환합니다. 따라서 컴파일러에 경고를 추가하면 많은 기존 코드에 대해 가짜 경고가 발생할 수 있습니다. POSIX는 이것을 ssize_t 로 코드화하려고 시도하지만 ssize_t 의 최대 부호 값보다 큰 반환 값으로 성공할 수있는 호출을 중단합니다.





size-t