问题 Microsoft C编译器:内联变量声明?


我在Visual Studio 2010中编写C语言。编译器似乎不想让我使用内联变量声明。以下代码生成错误:

unsigned int fibonacci_iterative(unsigned int n) {
 if (n == 0) {
  return 0;
 }
 if (n == 1) {
  return 1;
 }

 unsigned int prev_prev = 0; // error
 unsigned int prev = 1; // error
 unsigned int next = 0; // error
 for (int term_number = 0; term_number < n; term_number++) {
  unsigned int temp = prev_prev + prev;
  prev = next;
  prev_prev = prev;
  next = temp;
 }

 return next;
}

错误:

错误C2143:语法错误:丢失   ';'在'类型'之前

错误C2143:语法错误:丢失   ';'在'类型'之前

错误C2143:语法错误:丢失   ';'在'类型'之前

为什么会这样?是否有设置使编译器不那么严格?


5204
2018-01-31 02:42


起源



答案:


在C89中不允许在非声明之后放置声明,尽管在C ++和C99中允许它(但MSVC仍然不支持C99)。

在C89中,您可以通过使用嵌套块来实现类似的效果:

unsigned int fibonacci_iterative(unsigned int n) {
    if (...) {
    }

    {
       unsigned int prev_prev = 0;
       unsigned int prev = 1;
       unsigned int next = 0;
       ...
    }
 }

10
2018-01-31 02:52



虽然有点乱,不是吗?引用这些变量的所有其余函数都必须在块内,以便变量不会超出范围。如果过度使用,这将导致 非常 凌乱和大括号的代码。 - Chinmay Kanchi
@Chinmay:这取决于。是的,对于大块来说它可能会变得混乱,但它对于小块也很有用,其中一些变量只需要非常有限的范围。 - jamesdlin
这有多便携?这似乎可能是在寻找麻烦。 - Joel B
@JoelB:它是标准的C89,所以它应该是完全可移植的。 - jamesdlin


答案:


在C89中不允许在非声明之后放置声明,尽管在C ++和C99中允许它(但MSVC仍然不支持C99)。

在C89中,您可以通过使用嵌套块来实现类似的效果:

unsigned int fibonacci_iterative(unsigned int n) {
    if (...) {
    }

    {
       unsigned int prev_prev = 0;
       unsigned int prev = 1;
       unsigned int next = 0;
       ...
    }
 }

10
2018-01-31 02:52



虽然有点乱,不是吗?引用这些变量的所有其余函数都必须在块内,以便变量不会超出范围。如果过度使用,这将导致 非常 凌乱和大括号的代码。 - Chinmay Kanchi
@Chinmay:这取决于。是的,对于大块来说它可能会变得混乱,但它对于小块也很有用,其中一些变量只需要非常有限的范围。 - jamesdlin
这有多便携?这似乎可能是在寻找麻烦。 - Joel B
@JoelB:它是标准的C89,所以它应该是完全可移植的。 - jamesdlin


尝试将其编译为C ++。 C99将允许声明变量而不是作用域的顶部,但VC不知道C99。


1
2018-01-31 02:47



正如Chinmay所提到的,C和C ++在源代码级别并不完全兼容。 en.wikipedia.org/wiki/Compatibility_of_C_and_C++ - ephemient


内联变量声明仅在符合C99的编译器中受支持。 Microsoft Visual C ++似乎不符合C99(REF)。您将要么必须使用符合C99的编译器(GCC将在使用时使用内联变量编译代码 -std=c99)或在函数顶部声明变量。

编辑:或尝试C ++模式,如akallio所建议,虽然C和C ++并不严格相互兼容,所以如果(例如),你在C代码中使用任何特定于C ++的关键字,它将无法编译。


1
2018-01-31 02:49



除了关键字,关于指针转换的不同规则和 enum/struct/union 命名空间也可以使安全的C代码无法在C ++模式下编译。还有其他的花絮,比如 sizeof('a')==sizeof(int) 在C但是 sizeof('a')==sizeof(char) 在C ++中,但在实践中,这不是问题的常见原因。 - ephemient