Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么早期版本的C一开始就强制声明变量?_C++_C_Compiler Construction - Fatal编程技术网

C++ 为什么早期版本的C一开始就强制声明变量?

C++ 为什么早期版本的C一开始就强制声明变量?,c++,c,compiler-construction,C++,C,Compiler Construction,我已经浏览了一些C的历史,我发现在早期版本的C中,比如在C89标准中,必须在块的开头声明变量 但我也发现C99标准规范有一些放宽,在使用变量之前,可以在任何地方声明变量 我的问题是,为什么早期版本将其定为强制性?我的重点是要知道,在那些日子里,在设计编译器的过程中是否存在任何技术上的困难,这使得他们无法在任何时候识别声明 此外,我理解,从编译器设计的角度来看,在C89中有这样的限制,通过中间文件来存储映射,很容易处理变量声明和使用。但是有没有不使用中间文件(比如一些基于内存的存储)就可以处理这种

我已经浏览了一些C的历史,我发现在早期版本的C中,比如在C89标准中,必须在块的开头声明变量

但我也发现C99标准规范有一些放宽,在使用变量之前,可以在任何地方声明变量

我的问题是,为什么早期版本将其定为强制性?我的重点是要知道,在那些日子里,在设计编译器的过程中是否存在任何技术上的困难,这使得他们无法在任何时候识别声明


此外,我理解,从编译器设计的角度来看,在C89中有这样的限制,通过中间文件来存储映射,很容易处理变量声明和使用。但是有没有不使用中间文件(比如一些基于内存的存储)就可以处理这种情况的方法?

如果编译器预先看到所有本地/自动变量的合并列表,它可以立即计算出将堆栈指针移动到为它们保留堆栈内存的总量——只需对堆栈指针执行一次操作。如果它处理函数中遇到的点点滴滴中的变量,以增量方式移动堆栈指针,那么最终会出现更多专用于堆栈设置和堆栈指针更新的操作码。每当执行进一步的函数调用时,堆栈指针必须是最新的,这一点很重要。在考虑了所有函数之后,较新的编译器会做一些额外的工作,以补回移动堆栈指针的数量。(我想说的是,这种努力是如此之小,以至于早期的标准更多地是由提前知道该做什么的概念吸引力而不是更加灵活的努力形成的,但是如果你只是想让某些东西起作用,为什么要付出额外的努力呢?

C99的基本原理没有直接解释为什么C89不允许它,但他确实说它是在C99中添加的,因为它是在其他语言中被许可的,并且它被发现是有用的

§6.2.4物品的储存期限

C99:C89的一个新特性要求块中的所有声明都出现在任何语句之前。另一方面,许多类似于C的语言(如Algol68和C++)允许以任意方式混合声明和语句。此功能已被发现非常有用,并已添加到C99中


不需要中间文件来存储映射,而且从来没有。@AmrithKrishna您基本上是在问编译器如何使用数组…?关闭投票者,请在投票关闭此文件之前三思而后行,因为“主要基于意见”。OP要求对C89标准的一部分进行技术论证。@FpggyDay:你错得太离谱了,这太令人惊讶了(将数据和代码的范围缩小到实际有用的地方,并将有意义的值分配到可以使用的地方,这是可维护编程的基本原则),你越来越觉得这个问题应该以观点为基础,从问题的技术方面转移到观点陈述中。别忘了,早在20世纪70年代初,当C首次被设计时,机器不一定有多达64KIB的内存(它们的内存更少!)。简化是让编译器执行的必要条件。考虑到这一点的必然结果是,在编译C89及之前的计算机史前时代,用户需要花费大量时间对每个块进行预解析,以找到所有的局部变量,然后再开始编译和发出代码,如果编译器是以这种一次性的方式构造的,那么您不需要回补吗(或者在函数中多次递增堆栈指针会导致效率低下)无论如何,因为新变量仍然可以在内部块内部声明?@sepp2k如果内部块在进入时分配堆栈内存,并在退出时释放它,这并不奇怪。@immibis在goto上如何?@ratchetfreak:你不能禁止goto进入具有自己声明的变量的块,C89允许它。C编译器必须通过考虑源代码和目标代码处的“环境”来处理goto,包括堆栈位置,可能还有哪些寄存器中的变量,并在跳转之前(或者不太可能,在跳转之后)进行必要的调整。所以
if(某物)转到X
不一定最终成为以X为目标的条件分支操作码,即使CPU有一个。