为什么微软的C编译器要在函数的开头添加变量?

时间:2021-05-11 05:27:13

I am currently writing a C (not C++). It seems the Microsoft's C compiler requires all variables to be declared on top of the function.

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

For example, the following code will not pass compilation:

例如,以下代码不会通过编译:

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

The compiler reports an error at the third line, saying

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

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

If the code is changed to be like below it will pass compilation:

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

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

If I change the source file name from .c to be .cpp, the compilation will also pass as well.

如果我将源文件名从.c更改为.cpp,编译过程也将通过。

I suspect there's an option somewhere to turn off the strictness of the compiler, but I haven't found it. Can anyone help on this?

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

Thanks in advance.

提前谢谢。

I am using cl.exe that is shipped with Visual Studio 2008 SP1.

我用cl。与Visual Studio 2008 SP1一起发货的exe。

Added:

补充道:

Thank you all for answering! It seems I have to live in C89 with Microsoft's cl.exe.

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

10 个解决方案

#1


33  

It looks like it's using C89 standard, which requires that all variables be declared before any code. You may initialize them with literals, etc., but not mix code and variables.

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

There should be a compiler flag to enable C99 somewhere, which will get you the behavior you're used to.

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

EDIT: quick Googling does not look promising for enabling C99. You may have to live with C89 (which ain't so bad) or find a better C compiler (which would be better).

编辑:快速搜索不希望启用C99。您可能必须使用C89(这并不是很糟糕)或者找到更好的C编译器(这将更好)。

#2


7  

Microsoft C compiler is C89 compilant, and isn't upgraded anymore, the standard C99 isn't afaik planned. For plain C in C99 (variables not on begin of block) use another compiler, or C++ extension.

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

#3


3  

As others have said, this is just the version of C which MSC supports. However, if you're prepared to offend the purists, you can just force the compiler to compile as C++.

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

This will make very little difference to pure C (there are some rules about casting void* pointers, and name decoration changes), but might give you a useful hybrid. The code generated will be much the same - there is no magical loss (or gain) of efficiency by making this change.

这对纯C来说没什么区别(有一些关于释放void*指针和更改名称的规则),但是可能会给您一个有用的混合。生成的代码将是相同的——通过进行这种更改,没有任何神奇的损失(或获得)。

You don't say why you're keen to use C.

你不会说你为什么喜欢用C。

#4


2  

I don't know for C99 but for earlier versions of the language local variables must be declared at the beginning of a { } block.

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

#5


1  

In C90, all variables have to be declared before the first statement. This is not the case in C99. I suppose you can see if the compiler has a switch for C99.

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

#6


1  

It makes it easier to translate to assembly. All the variables are pushed onto the stack when you enter the function, so you don't have to worry about doing it anywhere else.

它使转换到程序集变得更容易。当您输入函数时,所有的变量都被推到堆栈中,所以您不必担心在其他地方做这个操作。

#7


1  

Agree with the comment about the C spec. Remember that C was created in a time when computers didn't have a lot of memory.

同意关于C规范的评论。请记住,C是在计算机内存不足的时代创建的。

One way to deal with that was to make sure that a source file could be read in a single pass from top to bottom (which is also the reason why .h-files are used -> they tell the code that certain functions do indeed exist, but possibly somewhere after the first time that they are referenced).

处理的一种方法,是确保源文件可以一次通过阅读从上到下(这也是为什么.h-files - >他们告诉使用某些功能的代码确实存在,但可能某个地方后,他们第一次被引用)。

It's probably easier to create a compiler for code that declares variables at the top of a scope than it is for code that can declare variables anywhere.

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

#8


1  

The C89 standard, which you must be using based on this error, requires the variables to be declared before you start executing statements in any block.

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

You won't be having this problem with .cpp extension files because the compiler will be treating these as C++ files, which doesn't have the same restriction.

对于.cpp扩展文件,您不会遇到这个问题,因为编译器将这些文件视为c++文件,而c++文件没有同样的限制。

Your assert statement is code so you can't declare a variable after that (in the same block/scope).

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

Technically you could do this:

技术上来说,你可以这样做:

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

but I wouldn't advise it.

但我不建议这么做。

#9


1  

It's a shame that MS doesn't implement mixed declarations and statements as an extension to the C compiler (even if it's off by default and needs to be switched on). I'm not certain, but I think it's a pretty common extension in other non-C99 C compilers; it seems like often enough I have to fix up source and samples to compile in MSVC.

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

I'd think it would be relatively easy to implement, since of course they already do it for C++.

我认为实现起来比较容易,因为他们已经在c++中实现了。

#10


0  

The C spec requires that all variables be declared prior to the first line of executable code. The compiler is adhering to the spec. Some compilers are lenient in this regard.

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

#1


33  

It looks like it's using C89 standard, which requires that all variables be declared before any code. You may initialize them with literals, etc., but not mix code and variables.

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

There should be a compiler flag to enable C99 somewhere, which will get you the behavior you're used to.

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

EDIT: quick Googling does not look promising for enabling C99. You may have to live with C89 (which ain't so bad) or find a better C compiler (which would be better).

编辑:快速搜索不希望启用C99。您可能必须使用C89(这并不是很糟糕)或者找到更好的C编译器(这将更好)。

#2


7  

Microsoft C compiler is C89 compilant, and isn't upgraded anymore, the standard C99 isn't afaik planned. For plain C in C99 (variables not on begin of block) use another compiler, or C++ extension.

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

#3


3  

As others have said, this is just the version of C which MSC supports. However, if you're prepared to offend the purists, you can just force the compiler to compile as C++.

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

This will make very little difference to pure C (there are some rules about casting void* pointers, and name decoration changes), but might give you a useful hybrid. The code generated will be much the same - there is no magical loss (or gain) of efficiency by making this change.

这对纯C来说没什么区别(有一些关于释放void*指针和更改名称的规则),但是可能会给您一个有用的混合。生成的代码将是相同的——通过进行这种更改,没有任何神奇的损失(或获得)。

You don't say why you're keen to use C.

你不会说你为什么喜欢用C。

#4


2  

I don't know for C99 but for earlier versions of the language local variables must be declared at the beginning of a { } block.

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

#5


1  

In C90, all variables have to be declared before the first statement. This is not the case in C99. I suppose you can see if the compiler has a switch for C99.

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

#6


1  

It makes it easier to translate to assembly. All the variables are pushed onto the stack when you enter the function, so you don't have to worry about doing it anywhere else.

它使转换到程序集变得更容易。当您输入函数时,所有的变量都被推到堆栈中,所以您不必担心在其他地方做这个操作。

#7


1  

Agree with the comment about the C spec. Remember that C was created in a time when computers didn't have a lot of memory.

同意关于C规范的评论。请记住,C是在计算机内存不足的时代创建的。

One way to deal with that was to make sure that a source file could be read in a single pass from top to bottom (which is also the reason why .h-files are used -> they tell the code that certain functions do indeed exist, but possibly somewhere after the first time that they are referenced).

处理的一种方法,是确保源文件可以一次通过阅读从上到下(这也是为什么.h-files - >他们告诉使用某些功能的代码确实存在,但可能某个地方后,他们第一次被引用)。

It's probably easier to create a compiler for code that declares variables at the top of a scope than it is for code that can declare variables anywhere.

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

#8


1  

The C89 standard, which you must be using based on this error, requires the variables to be declared before you start executing statements in any block.

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

You won't be having this problem with .cpp extension files because the compiler will be treating these as C++ files, which doesn't have the same restriction.

对于.cpp扩展文件,您不会遇到这个问题,因为编译器将这些文件视为c++文件,而c++文件没有同样的限制。

Your assert statement is code so you can't declare a variable after that (in the same block/scope).

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

Technically you could do this:

技术上来说,你可以这样做:

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

but I wouldn't advise it.

但我不建议这么做。

#9


1  

It's a shame that MS doesn't implement mixed declarations and statements as an extension to the C compiler (even if it's off by default and needs to be switched on). I'm not certain, but I think it's a pretty common extension in other non-C99 C compilers; it seems like often enough I have to fix up source and samples to compile in MSVC.

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

I'd think it would be relatively easy to implement, since of course they already do it for C++.

我认为实现起来比较容易,因为他们已经在c++中实现了。

#10


0  

The C spec requires that all variables be declared prior to the first line of executable code. The compiler is adhering to the spec. Some compilers are lenient in this regard.

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