views:

483

answers:

3

I'm writing C in Visual Studio 2010. The compiler doesn't seem to want to let me use inline variable declarations. The following code produces an error:

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;
}

Error:

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

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

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

Why is this happening? Is there a setting to make the compiler not so strict?

+1  A: 

Try to compile it as C++. C99 will allow variables to be declared other than the top of scope, but VC doesn't know about C99.

Arthur Kalliokoski
As Chinmay mentions, C and C++ aren't fully compatible at the source level. http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++
ephemient
+1  A: 

Inline variable declarations are only supported in a C99 compliant compiler. Microsoft Visual C++ doesn't seem to be C99-compliant (ref). You're either going to have to use a C99-compliant compiler (GCC will compile code with inline variables when used with -std=c99) or declare your variables at the top of the function.

EDIT: Or try C++ mode, as suggested by akallio, though C and C++ aren't strictly compatible with each other, so if (for example), you use any C++-specific keywords in your C code, it won't compile.

Chinmay Kanchi
Keyword aside, different rules about pointer casting and `enum/struct/union` namespaces can also make safe C code fail to compile in C++ mode. There's other tidbits, like `sizeof('a')==sizeof(int)` in C but `sizeof('a')==sizeof(char)` in C++, but in practice that's not a common cause of problems.
ephemient
+4  A: 

Putting declarations after non-declarations isn't allowed in C89, although it is allowed in C++ and in C99 (MSVC still doesn't support C99, though).

In C89, you can achieve a similar effect by using a nested block:

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

    {
       unsigned int prev_prev = 0;
       unsigned int prev = 1;
       unsigned int next = 0;
       ...
    }
 }
jamesdlin
A bit messy though, isn't it? All the rest of the function that references those variables will have to be inside the block so that the variables don't go out of scope. If overused, this will lead to _very_ messy and brace-heavy code.
Chinmay Kanchi
@Chinmay: It depends. Yeah, it could end being messy for large blocks, but it also can be useful for small blocks where some variables need only a very limited scope.
jamesdlin