如何重新编写代码以实现相同的测试,但可移植避免警告?
AFAIK,INT_MAX
和SIZE_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?
答案 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_t
或uintmax_t
)。
#if (INT_MAX+0U) > SIZE_MAX
assert(size <= (int)SIZE_MAX);
#endif
然后在#if
内,您知道SIZE_MAX
少于INT_MAX
,因此您可以在不更改值的情况下将其强制转换为int
。