The keyword was inherited from B.
B was a programming language with no type system at all: every variable held a machine word (corresponding to the int type in C), and the type of each value was determined by the operation performed. Since there was no type to specify for variables, the only thing to declare about a variable was its storage class; unlike in C, the default in B corresponded to C’s static, i.e. a variable that existed for the duration of the whole program’s run time. Thus the auto keyword was included to denote automatic variables, which existed only for the duration of a single function call. The term automatic itself came from PL/I, from which B also borrowed the /* ... */ comment syntax.
While C added type declarations, int was kept as the implicit default, and it was still possible to declare int variables with only the storage class specifier, just like in B. In the early days of C, it was common to rely on this. Here’s for example the famous Duff’s device from 1983:
send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}
Duff omits any type specifiers for the count parameter, the n variable and the return type of send; all are assumed to be int. (Since he doesn’t actually return any value from the function, he would have probably used void for the return type in modern C, but that barely existed back then.) The K&R-style declaration for function parameters he uses for the send function is also a straightforward extension of B syntax.
We can therefore surmise that the auto keyword was included ‘for symmetry’ with other storage class specifiers, to support this coding style that relied on implicit int; this also eased porting B code into C. Whether compatibility with B code was an explicit goal or just an emergent property coming from the fact that the first C compiler grew out of a B compiler, I don’t know. But it was probably a consideration.
Over the years, implicit int fell into disuse (with contemporary compilers emitting warnings against it), and with it, the auto keyword as well. (I’d assume auto was never popular in C in the first place, as int is one character shorter, so everyone declared the type anyway.) With the B language extinct, and B-derived K&R C displaced by ISO C, the keyword became redundant.
registerstorage qualifier can offer a huge performance boost, sometimes allowing loops to execute just as fast in-O0mode as they would with optimizations enabled. – supercat Dec 14 '20 at 18:28autokeyword had so little impact on that is quite remarkable. – user3840170 Dec 14 '20 at 22:32autoin C code – Jean-François Fabre Dec 14 '20 at 22:39->has been moved to chat. – wizzwizz4 Dec 15 '20 at 11:59registerkeyword was quite handy. That compiler did very little optimizing - so little that I was able to disassemble machine code and pretty much decompile the result in my head. One we had working code, we'd go back and selectively addregisterhere and there to speed things up – Flydog57 Dec 30 '20 at 00:59autofor type deduction came from the D language where it was used for that purpose for a very long time now. Long before C++ even contemplated it. Contrary to C++ auto is still categorized as storage category, which means that type inference works by omitting the type and the rvalue's type is taken for the type of the declared variable.auto a=whatever,const a=whatever,immutable a=whateverandstatic a=whateverall are valid declarations inferring the type of a from the type ofwhatever. – Patrick Schlüter Jan 18 '21 at 08:50