17

此声明在 g++ -pedantic -Wall(版本 4.6.3)中编译时没有警告:

std::size_t foo = -42;

不太明显的虚假是用 size_t 参数声明一个函数,并用一个负值调用它。这样的函数能否防止无意的否定论点(显示为无数的 quintillion,遵守 §4.7/2)?

不完整的答案:

只需将 size_t 更改为 (signed) long 就会放弃 size_t 的语义和其他优点。

将其更改为 ssize_t 仅仅是 POSIX,而不是标准。

将其更改为 ptrdiff_t 很脆弱,有时会损坏。

测试大值(高位设置等)是任意的。

4

2 回答 2

3

对此发出警告的问题在于,根据标准,它不是未定义的行为。如果将有符号值转换为相同大小的无符号类型,则可以稍后将其转换回有符号值并在任何符合标准的编译器上获取原始值。

此外,对于各种错误情况,使用转换为 size_t 的负值是相当普遍的做法——许多系统调用返回一个无符号 (size_toff_t) 值表示成功或返回 -1(转换为无符号)表示错误。因此,向编译器添加这样的警告会导致许多现有代码出现虚假警告。POSIX 尝试将其编码为ssize_t,但这会破坏可能成功的调用,其返回值大于 的最大有符号值ssize_t

于 2013-03-29T19:52:37.880 回答
2

以下摘录来自私人图书馆。

#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))

This should work with all unsigned types.

于 2016-01-18T17:37:11.367 回答