为什么 C 不定义数组的最小大小? [英] Why does C not define minimum size for an array?

查看:61
本文介绍了为什么 C 不定义数组的最小大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C 标准定义了很多下限/上限(翻译限制) 并强加实现应满足每个翻译.为什么没有为数组大小定义这样的最小限制?以下程序将编译良好,可能会产生运行时错误/段错误,并会调用未定义的行为.

C standard defines a lot of lower/upper limits (translation limits) and imposes an implementation should satisfy for each translation. Why there's no such minimum limit defined for an array size? The following program is going to compile fine and likely produce runtime error/segfault and would invoke undefined behaviour.

int main()
{
   int a[99999999];
   int i;

   for(i=0;i<99999999;i++)
   a[i]=i;

   return 0;
}

一个可能的原因可能是本地数组是在自动存储上分配的,这取决于分配的堆栈帧的大小.但是为什么不是像 C 定义的其他限制那样的最小限制?

A possible reason could be local arrays are allocated on automatic storage and it depends on the size of the stack frame allocated. But why not a minimum limit like other limits defined by C?

让我们忘记上面的未定义情况.考虑以下几点:

Let's forget about the undefined cases like above. Consider the following:

int main()
{
   int a[10];
   int i;

   for(i=0;i<10;i++)
   a[i]=i;

   return 0;
}

在上面,是什么让我保证本地数组(尽管很小)将按预期工作并且不会由于分配失败而导致未定义的行为?

In the above, what gives me the guarantee that the local array (despite a very small one) is going to work as expected and won't cause undefined behaviour due to allocation failure?

尽管在任何现代系统上分配如此小的阵列不太可能失败.但是 C 标准没有定义要满足的任何要求,并且编译器不会(至少 GCC 不会)报告分配失败.只有运行时错误/未定义的行为是可能的.困难的部分是没有人可以判断任意大小的数组是否会由于分配失败而导致未定义的行为.

Although it's unlikely that an allocation for such a small array would fail on any modern systems. But the C standard doesn't define any requirements to satisfy and compilers don't (at least GCC doesn't) report allocation failures. Only a runtime error/undefined behaviour is possibility. The hard part is nobody can tell whether an arbitrary sized array is going cause undefined behaviour due to allocation failure.

请注意,我知道我可以为此目的使用动态数组(通过 malloc 和朋友),并且可以更好地控制分配失败.我更感兴趣的是为什么没有为本地数组定义这样的限制.此外,全局数组将存储在静态存储中,并将增加编译器可以处理的可执行文件大小.

Note that I am aware I can use dynamic arrays (via malloc & friends) for this purpose and have a better control over allocation failures. I am more interested in why there's no such limit defined for local arrays. Also, global arrays are going to be stored in static storage and is going to increase executable size which compilers can handle.

推荐答案

MINIMUM 限制是一个包含 1 个元素的数组.为什么你会有一个限制"呢?当然,如果你永远递归地调用一个函数,一个 1 的数组可能不适合堆栈,或者调用函数 next 调用的调用可能不适合堆栈 - 解决这个问题的唯一方法是知道编译器中堆栈的大小 - 但编译器在那个阶段实际上并不知道堆栈有多大 - 别介意极其复杂的调用层次结构的问题是几个不同的函数调用同一个函数,可能带有递归和/或堆栈的几层相当大的消费者 - 你如何调整堆栈的大小 - 可能不会遇到最坏的情况,因为其他事情表明这不会发生 - 例如,一个函数中的最坏情况只是当输入文件为空时,但另一个函数中最坏的情况是同一文件中存储了大量数据.很多很多这样的变化.确定它太不可靠了,所以迟早它会变成猜测或大量误报.

The MINIMUM limit is an array of 1 element. Why would you have a "limit" for that? Of course, if you call a function recursively forever, an array of 1 may not fit on the stack, or the call that calls the function next call around may not fit on the stack - the only way to solve that would be to know the size of the stack in the compiler - but the compiler doesn't actually know at that stage how big the stack is - never mind the problems of extremely complex call hierarchies were several different functions call into the same function, possibly with recursion and/or several layers of rather large consumers of stack - how do you size the stack for that - the worst possible case may not be ever encountered, because other things dictate that this doesn't happen - for example, the worst case in one function is only when an input file is empty, but the worst case in another function is when there is lots of data stored in the same file. Lots and lots of variations like this. It's just too unreliable to determine, so sooner or later it would just become guess-work or of lots of false positives.

考虑一个有数千个函数的程序,所有这些函数都调用同一个日志函数,需要堆栈上一个 200 字节的数组来临时存储日志输出.从 main 开始,几乎每个函数都会调用它.

Consider a program with thousands of functions, all of which call the same logging function that needs a 200 byte array on the stack for temporarily storing the log output. It's called from just about every function from main upwards.

局部变量的 MAXIMUM 取决于堆栈的大小,正如我上面所说,这不是编译器在编译代码时知道的 [链接器可能知道,但稍后会知道].对于全局数组和在堆上分配的数组,限制是您的进程可以获得多少内存",因此没有上限.

The MAXIMUM for a local variable depends on the size of the stack, which, like I said above, is not something the compiler knows when compiling your code [the linker MAY know, but that's later on]. For global arrays and those allocated on the heap, the limit is "how much memory your process can get", so there's no upper limit there.

没有简单的方法来确定这一点.并且标准提供的许多限制是为了保证代码可以在任何编译器"上编译,只要您的代码遵循规则.被编译和能够运行完成是两件不同的事情.

There's just no easy way to determine this. And many of the limits provided by the standard is there to guarantee that code can be compiled on "any compiler" as long as your code follows the rules. Be compiled and be able to run to completion is two different things.

int main(){同时(1);}

int main() { while(1); }

永远不会运行完成——但它会在我知道的每个编译器中编译,而且大多数人不会说存在无限循环——这是你的选择.

will never run to completion - but it will compile in every compiler I know of, and most won't say a thing about there being an infinite loop - it's your choice to do that.

将大型数组放入堆栈也是您的选择.并且很可能给链接器提供了几 GB 的堆栈,在这种情况下它会很好 - 或者堆栈是 200K,并且您不能有 50000 个整数数组...

It's also your choice to put large arrays on the stack. And it could well be that the linker is given several gigabytes of stack, in which case it'll be fine - or the stack is 200K, and you can't have 50000 array of integers...

这篇关于为什么 C 不定义数组的最小大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆