gcc7.2:参数范围超过最大对象大小9..7 [-Werror = alloc-size-larger-than =]

时间:2017-11-23 08:25:56

标签: c calloc gcc7

该程序包含如下代码:

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

错误消失了。

但是,在该计划中,有许多malloccalloc像我的原始版本一样使用。

为什么gcc只检测到一个错误?

3 个答案:

答案 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值,其参数nmembsize相乘。结果值显然可以超过最大对象大小。

编写良好的程序,以便永远不允许超出参数的值。但是,如果gcc无法找到此类检查,则会发出警告。强制转换为4个字节的整数将截断超出的值并使编译器满意。