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.