C++ 为什么微软';s C编译器希望变量位于函数的开头?

C++ 为什么微软';s C编译器希望变量位于函数的开头?,c++,c,C++,C,我目前正在写一个C(不是C++)。微软的C编译器似乎要求在函数顶部声明所有变量 例如,以下代码将无法通过编译: int foo(int x) { assert(x != 0); int y = 2 * x; return y; } int foo(int x) { int y; assert(x != 0); y = 2 * x; return y; } 编译器在第三行报告一个错误: error C2143: syntax error

我目前正在写一个C(不是C++)。微软的C编译器似乎要求在函数顶部声明所有变量

例如,以下代码将无法通过编译:

int foo(int x) {
    assert(x != 0);
    int y = 2 * x;
    return y;
}
int foo(int x) {
    int y;
    assert(x != 0);
    y = 2 * x;
    return y;
}
编译器在第三行报告一个错误:

error C2143: syntax error : missing ';' before 'type'
如果代码更改为如下所示,则将通过编译:

int foo(int x) {
    assert(x != 0);
    int y = 2 * x;
    return y;
}
int foo(int x) {
    int y;
    assert(x != 0);
    y = 2 * x;
    return y;
}
如果我将源文件名从
.c
更改为
.cpp
,编译也将通过

我怀疑有一个选项可以关闭编译器的严格性,但我还没有找到它。有人能帮忙吗

提前谢谢

我使用的是Visual Studio 2008 SP1附带的cl.exe

增加:


谢谢大家的回答!看来我不得不和微软的cl.exe一起住在C89

看起来它使用的是C89标准,它要求在任何代码之前声明所有变量。您可以使用文本等进行初始化,但不能混合使用代码和变量

应该有一个编译器标志来在某个地方启用C99,这将使您获得习惯的行为


编辑:快速谷歌搜索在启用C99方面似乎不太可能。您可能必须使用C89(还不错)或找到更好的C编译器(更好)。

必须基于此错误使用的C89标准要求在开始执行任何块中的语句之前声明变量

<> p>你不会因为.CPP扩展文件而有这个问题,因为编译器会把这些处理成C++文件,它们没有相同的限制。 assert语句是代码,因此在此之后不能声明变量(在同一块/范围内)

从技术上讲,您可以这样做:

int foo(int x) {
    assert(x != 0);
    {
        int y = 2 * x;
        return y;
    }
}

但是我不建议这样做。

对于C99我不知道,但是对于早期版本的语言,局部变量必须在{}块的开头声明。

在中,所有变量都必须在第一个语句之前声明。事实并非如此。我想您可以看到编译器是否有C99的开关。

C规范要求在第一行可执行代码之前声明所有变量。编译器遵循规范。一些编译器在这方面比较宽松。

这使它更容易转换为汇编。当您输入函数时,所有变量都会被推到堆栈上,因此您不必担心在其他任何地方执行此操作。

Microsoft C编译器是C89编译器,不再升级,标准C99也不再计划。对于C99中的C(变量不是在块开始)使用另一个编译器,或者C++扩展。

< P>同意C规范的注释。记住C是在计算机没有大量内存的时候创建的。 解决这个问题的一种方法是确保源文件可以从上到下一次性读取(这也是使用.h文件的原因->它们告诉代码某些函数确实存在,但可能在第一次引用它们之后的某个地方)


为在作用域顶部声明变量的代码创建编译器可能比为可以在任何地方声明变量的代码创建编译器更容易。

正如其他人所说,这正是MSC支持的C版本。但是,如果你准备冒犯纯系主义者,你可以强制编译器编译为C++。p> 这对纯C没有什么影响(有一些关于转换void*指针和名称修饰的规则),但可能会给你一个有用的混合。生成的代码基本相同-进行此更改不会导致效率的神奇损失(或增加)


你没有说为什么你热衷于使用C。

很遗憾,MS没有实现混合声明和语句作为C编译器的扩展(即使它在默认情况下是关闭的,需要打开)。我不确定,但我认为它是其他非C99 C编译器中非常常见的扩展;似乎我经常需要修改源代码和示例以在MSVC中编译


<>我认为这是比较容易实现的,因为他们已经为C++做了。

我正在搜索C.exe的帮助,以选择打开C99选项。但到目前为止我还不知道。要求在顶部声明所有变量似乎非常不方便。如果我使用gcc来编译代码,它就会工作。这是否意味着cl.exe不支持C99标准?Ryan:看起来cl.exe不支持C99,这是难以置信的。快10年了!谢谢你的回答!似乎我不得不使用C90 for cl.exe。您的印象是正确的。Microsoft不支持ANSI C99标准。AFAIK,没有编译器完全支持C99。对于MS编译器,它宣布没有计划引入C99特征。现代C,而不是古(微软,C89)不具有此限制。而一些C99的变化是复制C++标准,而C++0X标准(MSVC++将要遵守,至少部分地)会有一些C99一致性变化,C++不是C,C99标准之后更是如此,无论如何都不难。在生成代码之前构建符号表没有问题。变量不会“推送到堆栈”,堆栈指针只需修改。即使在函数顶部声明了所有变量,优化器在决定何时以及如何进行堆栈分配方面也有一定的回旋余地。不过,您可能希望将编译器标志设置为“C++减去异常”。