1

SuSv3ssize_t要求是有符号整数类型。如果我想检查我计算的值是否大于此类数据类型允许的最大值,我可以将其与 进行比较INT_MAX,这不太好。

是否有一种更便携的方式可以完成这种比较 - 一个宏/函数f,其工作方式如下

 f(<typedef'ed datatype>) = {maximum value allowed for <TDDT> on this system)?

, 或短序列的此类操作到相同的排序?

系统:
Ubuntu 12.04。
glibc 2.15
内核 3.2.0

PS:在谷歌上搜索时,我首先认为 gcc 扩展 'typeof' 听起来很有希望;但它似乎在这里没有帮助(或者是吗?)。这就是说我对任何可能是 gcc 扩展/属性/等的东西都很好。

4

1 回答 1

2

对于无符号算术类型,(type)-1是最大值。由于您不知道类型的相对大小是多少,请转换为uintmax_t

#define UNSIGNED_TYPE_MAX(t) ((uintmax_t)(t)-1)
if ((uintmax_t)x > UNSIGNED_TYPE_MAX(size_t)) puts("too large");

签名类型没有这样的快捷方式。事实上,我认为在严格可移植的 C89 或 C99 中没有任何方法可以确定带符号类型的最大值,而不使用相应的常量,例如SSIZE_MAXfor ssize_tstdint.hC99 为在 ISO C 中定义的类型中定义的算术设计的每种类型指定常量。对于在 POSIX 中定义但在标准 C 中没有定义的类型,在limits.h;中有很多值。请注意,它们是类型预期的有效值的限制,而不是可以适合类型的限制。例如,如果size_t是 32 位类型,则SIZE_MAX保证为 2 32 -1,而SSIZE_MAX可能小于 2 31-1 如果实现不支持任何大于此的字节数。

假设整数以二进制表示并且没有填充位,如果您将自己限制为 POSIX(其中始终为 8 ),这是安全的CHAR_BIT可以通过计算类型的大小来推断最大值:是有符号类型中的一个符号位,其他一切都是值位。

#define SIGNED_TYPE_MAX(t) (((uintmax_t)1 << (sizeof(t) * CHAR_BIT - 1)) - 1)

请注意,诸如“加倍直到停止增长”或“推入位模式 0111…111”之类的东西是不可靠的。C 标准表示有符号类型的行为是未定义的,GCC 利用这一点对有符号类型的操作执行优化,如果发生溢出,可能会导致错误值。例如,它可能在一个更大的寄存器中执行计算,这样溢出就不会发生。

于 2014-01-04T20:37:08.687 回答