我很想知道为什么当你尝试混合变量声明和代码时,C89编译器会转储到你身上,例如:
rutski@imac:~$ cat test.c
#include <stdio.h>
int
main(void)
{
printf("Hello World!\n");
int x = 7;
printf("%d!\n", x);
return 0;
}
rutski@imac:~$ gcc -std=c89 -pedantic test.c
test.c: In function ‘main’:
test.c:7: warning: ISO C90 forbids mixed declarations and code
rutski@imac:~$ 是的,你可以通过远离-pedantic来避免这种事情。但是,您的代码不再符合标准。任何能够回答这篇文章的人都可能已经知道,这不仅仅是一个理论上的问题。像微软的C编译器这样的平台在任何情况下都会在标准中快速执行这一点。
考虑到C语言是多么古老,我想这个特性是由一些历史问题造成的,可以追溯到70年代的非凡硬件限制,但我不知道细节。还是说我完全错了?
发布于 2011-06-27 12:22:12
C标准说“你不应该”,因为这在C89标准标准化的早期C编译器中是不允许的。对于创建一种可用于编写操作系统及其实用程序的语言来说,这是一个足够激进的步骤。这个概念可能根本没有被考虑过--当时没有其他语言允许它(Pascal,Algol,PL/1,Fortran,COBOL),所以C语言也不需要考虑。这可能会使编译器更难处理(更大),最初的编译器受到PDP 11系列中允许的64 KiB代码和64 KiB数据空间的空间限制(大型机器;较小的机器只允许64 KiB的代码和数据,AFAIK)。所以,额外的复杂性不是一个好主意。
允许声明和变量交错的是C++,但是C++不是,而且从来都不是C。然而,C99最终赶上了C++ (这是一个有用的特性)。遗憾的是,微软从未实现过C99。
发布于 2011-06-27 14:13:30
它可能从未以这种方式实现过,因为它从未被需要过。
假设你想用普通的C编写类似这样的代码:
int myfunction(int value)
{
if (value==0)
return 0;
int result = value * 2;
return result;
}然后,您可以轻松地用有效的C重写此代码,如下所示:
int myfunction(int value)
{
int result;
if (value==0)
return 0;
result = value * 2;
return result;
}首先声明变量,然后设置它的值,这绝对不会影响性能。
然而,在C++中,情况就不同了。在以下示例中,function2将比function1慢:
double function1(const Factory &factory)
{
if (!factory.isWorking())
return 0;
Product product(factory.makeProduct());
return product.getQuantity();
}
double function2(const Factory &factory)
{
Product product;
if (!factory.isWorking())
return 0;
product = factory.makeProduct();
return product.getQuantity();
}在function2中,即使工厂不工作,也需要构造产品变量。稍后,工厂生产产品,然后赋值操作符需要复制产品(从makeProduct的返回值到产品变量)。在function1中,产品只在工厂工作时构造,即使这样,也会调用复制构造函数,而不是普通的构造函数和赋值操作符。
然而,我现在期望一个好的C++编译器能够优化这段代码,但是在最初的C++编译器中,情况可能并非如此。
第二个示例如下:
double function1(const Factory &factory)
{
if (!factory.isWorking())
return 0;
Product &product = factory.getProduct();
return product.getQuantity();
}
double function2(const Factory &factory)
{
Product &product;
if (!factory.isWorking())
return 0;
product = factory.getProduct(); // Invalid. You can't assign to a reference.
return product.getQuantity();
}在本例中,function2是完全无效的。只能在声明时为引用赋值,而不能在以后赋值。这意味着在本例中,编写有效代码的唯一方法是在变量真正初始化时编写声明。不会更快。
这两个例子都说明了为什么在C++中需要在其他可执行语句之后声明变量,而不是像C那样在代码块的开头声明变量。这就解释了为什么要将它添加到C++中,而不是添加到不需要它的C(和其他语言)中。
发布于 2011-06-27 12:50:26
它类似于要求函数在使用之前被声明-它允许头脑简单的编译器从上到下一次操作,并在运行过程中发出目标代码。
在这种特殊情况下,编译器可以遍历声明,添加所需的堆栈空间。当它到达第一个语句时,它可以输出代码来调整堆栈,为本地变量分配空间,紧接在函数代码正确开始之前。
https://stackoverflow.com/questions/6488503
复制相似问题