为什么Microsoft的C编译器需要函数开头的变量?

时间:2009-04-01 13:34:37

标签: c++ c

我目前正在写一个C(不是C ++)。看来Microsoft的C编译器要求在函数之上声明所有变量。

例如,以下代码不会传递编译:

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

编译器在第三行报告错误,说

error C2143: syntax error : missing ';' before 'type'

如果代码更改为如下所示,它将通过编译:

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中。

10 个答案:

答案 0 :(得分:34)

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

应该有一个编译器标志在某处启用C99,这将为您提供您习惯的行为。

编辑:快速谷歌搜索对于启用C99看起来并不乐观。你可能不得不忍受C89(这不是那么糟糕)或找到一个更好的C编译器(这会更好)。

答案 1 :(得分:7)

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

答案 2 :(得分:3)

正如其他人所说,这只是MSC支持的C版本。但是,如果您准备冒犯纯粹主义者,您可以强制编译器以C ++编译。

这对纯C几乎没有什么影响(有关于编译void *指针和名称修饰的一些规则),但可能会给你一个有用的混合。生成的代码将大致相同 - 通过进行此更改,没有效率的神奇损失(或获得)。

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

.cpp扩展文件不会出现此问题,因为编译器会将这些文件视为C ++文件,这些文件没有相同的限制。

您的断言语句是代码,因此您不能在此之后声明变量(在相同的块/范围内)。

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

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

但我不建议。

答案 5 :(得分:1)

C90中,必须在第一个语句之前声明所有变量。 C99中不是这种情况。我想你可以看看编译器是否有一个C99开关。

答案 6 :(得分:1)

它可以更轻松地转换为汇编。当您输入函数时,所有变量都被压入堆栈,因此您不必担心在其他任何地方执行此操作。

答案 7 :(得分:1)

同意有关C规范的评论。请记住,C是在计算机没有大量内存的时候创建的。

解决这个问题的一种方法是确保源文件可以从上到下一次性读取(这也是使用.h文件的原因 - >它们告诉代码确定函数确实存在,但可能在第一次引用它们之后的某个地方。)

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

答案 8 :(得分:1)

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

我认为它实现起来相对容易,因为它们当然已经为C ++做了。

答案 9 :(得分:0)

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