如何在没有警告的情况下测试`int`到`size_t`转换“比较总是如此”?

时间:2014-03-06 20:49:47

标签: c warnings

如何重新编写代码以实现相同的测试,但可移植避免警告?


AFAIK,INT_MAXSIZE_MAX未定义为始终为> =而是另一个,因此使用以下函数来检测从int转换为{{}的问题1}}。

size_t

不同的编译器使用各种机制来压制警告。我正在寻找便携式解决方案。

上述解决方案不可移植,但遗憾的是,此#include <assert.h> #include <stddef.h> #include <stdint.h> size_t int_to_size_t(int size) { assert(size >= 0); #pragma GCC diagnostic ignored "-Wtype-limits" // Without the above pragma, below line of code may cause: // "warning: comparison is always true due to limited range of data type // [-Wtype-limits]" assert((unsigned)size <= SIZE_MAX); #pragma GCC diagnostic warning "-Wtype-limits" return (size_t) size; } 方法存在副作用:此代码后,现在启用了警告gcc,可能已启用,也可能未启用。不知道如何恢复-Wtype-limits设置。

价:
Portability of #warning preprocessor directive
Suppress comparison always true warning for Macros?

2 个答案:

答案 0 :(得分:7)

您可以替换它:

assert((unsigned)size <= SIZE_MAX);

由:

#if INT_MAX > SIZE_MAX
assert((unsigned)size <= SIZE_MAX);
#endif

如果#if条件为false,则assert条件始终为true,并且assert是不必要的。 (unsigned)强制转换是(可能)必须避免对有符号和无符号操作数之间的比较发出警告。

警告:我没有测试过这个。 (要对其进行全面测试,我需要访问int宽于size_t的系统,而且我从未见过这样的系统。)

答案 1 :(得分:2)

正如基思所说的那样,当INT_MAX的值大于SIZE_MAX的值时,你只需要担心。如果要在预处理器中比较这些值(并且您应该),则无法强制转换为使INT_MAX成为无符号类型。 (预处理器不知道演员表。)

因此,您必须在值中添加0U,以便两个表达式都变为uintmax_t。 (对于预处理器,整数常量为intmax_tuintmax_t)。

#if (INT_MAX+0U) > SIZE_MAX
assert(size <= (int)SIZE_MAX);
#endif

然后在#if内,您知道SIZE_MAX少于INT_MAX,因此您可以在不更改值的情况下将其强制转换为int