tags:

views:

953

answers:

10

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.

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.

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.

Added:

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

+27  A: 

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.

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

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).

dwc
+1.. but not for reminding me of the bad old days.
Dead account
I am searching the help of cl.exe for the option to switch on C99 options. But so far I got no clue on it. Requiring to declare all variables at the top seems extremely inconvenient.If I use gcc to compile my code it works. Does this mean the cl.exe does not support C99 standards?
yinyueyouge
Ryan: it appears that cl.exe does NOT support C99, which is incredible. It's been almost 10 years!
dwc
Thanks for answering! It seems I have to live with C90 for cl.exe.
yinyueyouge
Your impressions are correct Microsoft does not support the ANSI C99 standard.
Friedrich
AFAIK, no compiler fully supports C99. As for the MS compiler, it was announced that it is not planned to introduce the C99 features.
Nemanja Trifunovic
Why care about C99 when you can do C++, anyway? :)
snemarch
C++ has its place, but so does C
dwc
A: 

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.

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.

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.

cletus
Modern C, as opposed to archaic (Microsoft, C89) does not have this restriction.
Jonathan Leffler
+1  A: 

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

mouviciel
A: 

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.

Pesto
A: 

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.

JadeMason
C99 changed this.
Richard
A: 

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.

CookieOfFortune
It's not difficult in any case. There's no problem building the symbol table before generating code.
David Thornley
snemarch
+6  A: 

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.

Yossarian
While some C99 changes were made to copy the C++ standard, and the C++0x standard (which MSVC++ is going to conform to, at least in part) will have some C99-conformant changes, C++ is not C, and more so after the C99 standard.
David Thornley
A: 

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.

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).

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.

Lennaert
+2  A: 

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++.

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.

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

Will Dean
You probably want to set the compiler flags to "C++ minus exceptions", though.
MSalters
A: 

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.

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

Michael Burr