该程序包含如下代码:
int size;
...
int *pi = (int*)calloc(size, sizeof(int));
...
使用gcc7.2编译时出现错误消息:
错误:参数1范围[18446744071562067968,18446744073709551615]超出最大对象大小9223372036854775807 [-Werror = alloc-size-larger-than =]
当我改变时
int *pi = (int*)calloc(size, sizeof(int));
到
int *pi = (int*)calloc((unsigned int)size, sizeof(int));
错误消失了。
但是,在该计划中,有许多malloc
和calloc
像我的原始版本一样使用。
为什么gcc只检测到一个错误?
答案 0 :(得分:3)
我最近在GCC 9.1的构建中遇到了同样的问题,我在GCC Bugzilla上找到了这个讨论:
https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783
如链接讨论中所述,我能够通过对照PTRDIFF_MAX检查size参数来抑制警告。
答案 1 :(得分:1)
警告取决于GCC认为size
的范围。在程序中的特定点,它被认为是在(非常大的)范围内。在其他malloc / calloc callites上也许并不是那么大。
这在很大程度上取决于如何在程序的不同点计算size
。当然,确保 在任何使用之前实际初始化是第一步。
答案 2 :(得分:1)
该警告提到最大对象大小为9223372036854775807(0x7FFFFFFFFFFFFFFFFF)。它是实现定义的值。 size_t
必须足够大才能容纳该值,并且实际上,不带符号的话,它可能是该数字的两倍。 calloc()
函数将两个size_t
值,其参数nmemb
和size
相乘。结果值显然可以超过最大对象大小。
编写良好的程序,以便永远不允许超出参数的值。但是,如果gcc无法找到此类检查,则会发出警告。强制转换为4个字节的整数将截断超出的值并使编译器满意。