gcc7.2:参数范围超过最大对象大小 9..7 [-Werror=alloc-size-larger-than=]
Posted
技术标签:
【中文标题】gcc7.2:参数范围超过最大对象大小 9..7 [-Werror=alloc-size-larger-than=]【英文标题】:gcc7.2: argument range exceeds maximum object size 9..7 [-Werror=alloc-size-larger-than=] 【发布时间】:2017-11-23 08:25:55 【问题描述】:程序包含如下代码:
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 只检测到一个错误?
【问题讨论】:
size
真的没有初始化吗?
不,它应该已经在某个地方初始化了。
与您的问题无关,但您可能想阅读this question about casting the result of malloc
(and calloc
too)。
与您的问题更相关,您可以尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们吗?
18446744071562067968=2^64-2^31。 18446744073709551615=2^64-1。随心所欲。
【参考方案1】:
我最近在我的 GCC 9.1 版本中遇到了同样的问题,我在 GCC Bugzilla 上找到了这个讨论:
https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783
如链接讨论中所述,我可以通过对照 PTRDIFF_MAX 检查 size 参数来抑制警告。
【讨论】:
这个答案有什么问题?它通过显示错误报告的链接来回答问题并提供解决方法。我认为它不值得删除。【参考方案2】:警告提到最大对象大小为 9223372036854775807 (0x7FFFFFFFFFFFFFFF)。它是一个实现定义的值。 size_t
必须足够大以容纳该值,并且实际上,由于无符号,它可以取该数字的两倍。 calloc()
函数将两个 size_t
值相乘,其参数为 nmemb
和 size
。结果值显然可以超过最大对象大小。
编写好的程序被编码为永远不允许参数中的值超过。但是,如果 gcc 无法找到此类检查,则会发出警告。转换为 4 字节整数会截断超出的值并使编译器满意。
【讨论】:
【参考方案3】:警告取决于 GCC 认为 size
的范围。在程序中的那个特定点,它被认为在那个(非常大的)范围内。在其他 malloc/calloc 调用站点,它可能没有那么大。
这在很大程度上取决于如何在程序的不同点计算size
。当然,在任何使用之前确保它被实际初始化是第一步。
【讨论】:
以上是关于gcc7.2:参数范围超过最大对象大小 9..7 [-Werror=alloc-size-larger-than=]的主要内容,如果未能解决你的问题,请参考以下文章
c语言 %d %f %lf %d可表示的最大和最小范围是多少?超过了范围 计算机怎么显示