4

该程序包含如下代码:

int size;
...
int *pi = (int*)calloc(size, sizeof(int));
...

下面是用gcc7.2编译时的错误信息:</p>

错误:参数 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 只检测到一个错误?

4

3 回答 3

5

我最近在我的 GCC 9.1 版本中遇到了同样的问题,我在 GCC Bugzilla 上找到了这个讨论:

https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783

如链接讨论中所述,我能够通过对照 PTRDIFF_MAX 检查 size 参数来抑制警告。

于 2019-06-21T12:23:35.323 回答
2

警告提到最大对象大小为 9223372036854775807 (0x7FFFFFFFFFFFFFFF)。它是一个实现定义的值。 size_t必须足够大以容纳该值,并且实际上,由于无符号,它可以取该数字的两倍。该calloc()函数将两个值相乘size_t,即它的参数nmembsize。结果值显然可以超过最大对象大小。

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

于 2020-08-12T08:34:53.053 回答
1

警告取决于 GCC 认为的范围size。在程序中的那个特定点,它被认为在那个(非常大的)范围内。在其他 malloc/calloc 调用站点,它可能没有那么大。

这在很大程度上取决于size程序中不同点的计算方式。当然,第一步是确保在任何使用之前实际初始化

于 2017-11-23T08:34:12.463 回答