Why does auto a=1; compile in C?

lee77 picture lee77 · May 1, 2014 · Viewed 36k times · Source

The code:

int main(void)
{
    auto a=1;
    return 0;
}

gets compiled without errors by the MS Visual Studio 2012 compiler, when the file has the .c extension. I have always thought that when you use the .c extension, compilation should be according to the C syntax, and not C++. Moreover, as far as I know auto without a type is allowed only in C++ since C++11, where it means that the type is deduced from the initializer.

Does that mean that my compiler isn't sticking to C, or is the code actually correct in C-language?

Answer

Fred Foo picture Fred Foo · May 1, 2014

auto is an old C keyword that means "local scope". auto a is the same as auto int a, and because local scope is the default for a variable declared inside a function, it's also the same as int a in this example.

This keyword is actually a leftover from C's predecessor B, where there were no base types: everything was int, pointer to int, array of int.(*) Declarations would be either auto or extrn [sic]. C inherited the "everything is int" as a default rule, so you could declare integers with

auto a;
extern b;
static c;

ISO C got rid of this, but many compilers still accept it for backward compatibility. If it seems unfamiliar, then you should realise that a related rule is at work in

unsigned d;  // actually unsigned int

which is still common in modern code.

C++11 reused the keyword, which few if any C++ programmers were using with the original meaning, for its type inference. This is mostly safe because the "everything is int" rule from C had already been dropped in C++98; the only thing that breaks is auto T a, which no-one was using anyway. (Somewhere in his papers on the history of the language, Stroustrup comments on this, but I can't find the exact reference right now.)

(*) String handling in B was interesting: you'd use arrays of int and pack multiple characters in each member. B was actually BCPL with different syntax.