85

Note this question was originally posted in 2009, before C++11 was ratified and before the meaning of the auto keyword was drastically changed. The answers provided pertain only to the C++03 meaning of auto -- that being a storage class specified -- and not the C++11 meaning of auto -- that being automatic type deduction. If you are looking for advice about when to use the C++11 auto, this question is not relevant to that question.

For the longest time I thought there was no reason to use the static keyword in C, because variables declared outside of block-scope were implicitly global. Then I discovered that declaring a variable as static within block-scope would give it permanent duration, and declaring it outside of block-scope (in program-scope) would give it file-scope (can only be accessed in that compilation unit).

So this leaves me with only one keyword that I (maybe) don't yet fully understand: The auto keyword. Is there some other meaning to it other than 'local variable?' Anything it does that isn't implicitly done for you wherever you may want to use it? How does an auto variable behave in program scope? What of a static auto variable in file-scope? Does this keyword have any purpose other than just existing for completeness?

Melebius
  • 4,692
  • 3
  • 32
  • 43
Carson Myers
  • 34,352
  • 35
  • 118
  • 164

10 Answers10

85

In C++11, auto has new meaning: it allows you to automatically deduce the type of a variable.

Why is that ever useful? Let's consider a basic example:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

The auto there creates an iterator of type std::list<int>::iterator.

This can make some seriously complex code much easier to read.

Another example:

int x, y;
auto f = [&]{ x += y; };
f();
f();

There, the auto deduced the type required to store a lambda expression in a variable. Wikipedia has good coverage on the subject.

fredoverflow
  • 237,063
  • 85
  • 359
  • 638
std''OrgnlDave
  • 3,664
  • 21
  • 30
  • 4
    Still not sure if this is a great use of auto. Code should be easy to read, not easy to write! – DanDan Jun 14 '12 at 21:52
  • 38
    I dunno about you but I find this much easier to read than iterator type spam. – Overv Jun 14 '12 at 21:58
  • 17
    And if for some reson zou decide to change class from list to some other class, you dont have to search for every iterator declaration and change it. – roslav Aug 24 '12 at 10:49
  • 1
    Can it also figure out where you want `std::list::const_iterator` versus `std::list::iterator` ? – KarateSnowMachine Oct 12 '13 at 21:42
  • 2
    @KarateSnowMachine: If you wanted the const, you would use "const auto" instead of "auto". – darth happyface Nov 13 '13 at 16:23
  • One great advantage is that you can change containers type afterwards if iterator is using auto. auto IT = myList.begin(); instead of std::list::const_iterator IT = myList.begin(); will still work if myList is a std::list or a std::vector – Korchkidu Dec 14 '13 at 08:53
  • 4
    @darth `const auto it = a.begin();` would give you a const `iterator`, not a `const_iterator`. You chould still change the element, but `++it` would fail to compile. To get a `const_iterator`, you would use `auto it = a.cbegin();` – fredoverflow Dec 14 '13 at 09:45
  • 1
    There are some cases where the return type of a standard library function is unspecified and you MUST use auto to capture the return value. – LB-- Jan 02 '14 at 03:00
  • 1
    @underscore_d `std::bind` for example. – LB-- Apr 16 '16 at 17:29
  • @LB-- Thanks! I knew `auto` was required for lambdas but not `bind`, but it makes sense that the latter needs it too. – underscore_d Apr 16 '16 at 17:38
  • Wow, can't believe this is still active! I wanted to chime in and add that using the C++11-style iterating for loops, you can get const, non-const and reference iterators. for (auto &it : whatever) {} will iterate over any standard library-compatible object such as a list, and the & ensures that the iterator points to elements, instead of copies of them – std''OrgnlDave May 20 '16 at 15:51
74

auto is a storage class specifier, static, register and extern too. You can only use one of these four in a declaration.

Local variables (without static) have automatic storage duration, which means they live from the start of their definition until the end of their block. Putting auto in front of them is redundant since that is the default anyway.

I don't know of any reason to use it in C++. In old C versions that have the implicit int rule, you could use it to declare a variable, like in:

int main(void) { auto i = 1; }

To make it valid syntax or disambiguate from an assignment expression in case i is in scope. But this doesn't work in C++ anyway (you have to specify a type). Funny enough, the C++ Standard writes:

An object declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default. [Note: hence, the auto specifier is almost always redundant and not often used; one use of auto is to distinguish a declaration-statement from an expression-statement (6.8) explicitly. — end note]

which refers to the following scenario, which could be either a cast of a to int or the declaration of a variable a of type int having redundant parentheses around a. It is always taken to be a declaration, so auto wouldn't add anything useful here, but would for the human, instead. But then again, the human would be better off removing the redundant parentheses around a, I would say:

int(a);

With the new meaning of auto arriving with C++0x, I would discourage using it with C++03's meaning in code.

simonet
  • 285
  • 1
  • 13
Johannes Schaub - litb
  • 466,055
  • 116
  • 851
  • 1,175
  • I didn't know you could do that--which C is this? Pre-ANSI? – Carson Myers Jun 25 '09 at 22:18
  • It will work in the next standard release of C++. I never thought of auto i = 1. Most examples of the new usage use auto i = container.begin() – Zan Lynx Jun 25 '09 at 22:20
  • 4
    C++ compilers often used to have implicit int for return values from functions, back in the ARM days before the standard... Before the EMPIRE... – Daniel Earwicker Jun 25 '09 at 22:21
  • @Carson, it's standard in C89. The use of implicit-int however is obsolescent even there, and is banned from C99 too, and was never standard in C++. – Johannes Schaub - litb Jun 25 '09 at 22:26
  • Interesting, I didn't know about that little nuance with implicit-int. – Adam Rosenfield Jun 25 '09 at 22:26
  • 1
    I just recognized it as my compilers way of telling me I forgot to forward-declare a function. It would tell me that my usage of a function was different from the way it was declared because of implicit int. – Carson Myers Jun 25 '09 at 23:04
  • 29
    The best part is that programmers used to write "auto" (four letters) to save themselves from writing "int" (three letters). – Max Lybbert Jun 25 '09 at 23:36
  • 30
    @Max - hey, a lot of people say "double-u-double-u-double-u" as an abbreviation of "World Wide Web". – Daniel Earwicker Jun 26 '09 at 00:07
  • Isn't "volatile" a storage class specifier as well? – smichak May 13 '12 at 09:19
  • 3
    @smichak no, "volatile" is a type qualifier. Rather than determining where to store a value, it changes the behavior of a write to and read from an object of the volatile qualified type. There can be volatile qualified stack variables (auto storage class) aswell as volatile qualified static storage duration variables (local 'static' storage class, non-local variables). Aside that, I don't know whether "register volatile" is a valid combination :) – Johannes Schaub - litb May 13 '12 at 09:29
  • for(auto value : map) {} – Volodymyr B. Aug 27 '13 at 21:45
35

The auto keyword has no purpose at the moment. You're exactly right that it just restates the default storage class of a local variable, the really useful alternative being static.

It has a brand new meaning in C++0x. That gives you some idea of just how useless it was!

Daniel Earwicker
  • 108,589
  • 35
  • 194
  • 274
  • 1
    oh man, is that ever useless. I like the new meaning though. It makes some code a lot less verbose and redundant. – Carson Myers Jun 25 '09 at 22:17
  • Yes, having used the equivalent in C# it will probably make a huge difference. More so in C++ if you're using expression templates where the types are so complex that they were never intended to be written out by hand. – Daniel Earwicker Jun 25 '09 at 22:22
7

GCC has a special use of auto for nested functions - see here.

If you have nested function that you want to call before its definition, you need to declare it with auto.

qrdl
  • 31,423
  • 13
  • 52
  • 82
3

"auto" supposedly tells the compiler to decide for itself where to put the variable (memory or register). Its analog is "register", which supposedly tells the compiler to try to keep it in a register. Modern compilers ignore both, so you should too.

T.E.D.
  • 41,324
  • 8
  • 64
  • 131
  • 1
    Not exactly - if you declare it with "register", compilers don't let you use the address-of operator (&foo) on the variable because, well, it doesn't exist anywhere in memory (and thus has no address). – Tim Čas Dec 12 '11 at 10:57
3

I use this keyword to explicitly document when it is critical for function, that the variable be placed on the stack, for stack-based processors. This function can be required when modifying the stack prior to returning from a function (or interrupt service routine). In this case I declare:

auto unsigned int auiStack[1];   //variable must be on stack

And then I access outside the variable:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

So the auto keyword helps document the intent.

Eldar Abusalimov
  • 21,255
  • 4
  • 60
  • 66
luke
  • 31
  • 1
  • 1
    I assume this is _only_ signalling intent, since the keyword does not actually enforce stack placement, anymore than simply omitting it would do. – underscore_d Apr 16 '16 at 12:43
2

According to Stroustrup, in "The C Programming Language" (4th Edition, covering C 11), the use of 'auto' has the following major reasons (section 2.2.2) (Stroustrup words are quoted):

1)

The definition is in a large scope where we want to make the type clearly visible to readers of our code.

With 'auto' and its necessary initializer we can know the variable's type in a glance!

2)

We want to be explicit about variable's range or precision (e.g., double rather than float)

In my opinion a case that fits here, is something like this:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

Using 'auto' we avoid redundancy and writing long type names.

Imagine some long type name from a templatized iterator:

(code from section 6.3.6.1)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}
wesley.mesquita
  • 797
  • 5
  • 12
1

In old compiler, auto was one way to declare a local variable at all. You can't declare local variables in old compilers like Turbo C without the auto keyword or some such.

chaz
  • 1
  • 1
  • I'm afraid you are mistaken. There was never any such constraint, even in Turbo C's original version called Wizard-C back in 1986, or any of its contemporaries: MSC, Lattice C, Concurrent-C, High-C, Watcom-C... – chqrlie Nov 24 '20 at 20:05
1

Is there some other meaning to 'auto' other than 'local variable?'

Not in C++03.

Anything it does that isn't implicitly done for you wherever you may want to use it?

Nothing whatsoever, in C++03.

How does an auto variable behave in program scope? What of a static auto variable in file-scope?

Keyword not allowed outside of a function/method body.

Does this keyword have any purpose [in C++03] other than just existing for completeness?

Surprisingly, yes. C++ design criteria included a high degree of backward compatibility with C. C had this keyword and there was no real reason to ban it or redefine its meaning in C++. So, the purpose was one less incompatibility with C.

Does this keyword have any purpose in C other than just existing for completeness?

I learned one only recently: ease of porting of ancient programs from B. C evolved from a language called B whose syntax was quite similar to that of C. However, B had no types whatsoever. The only way to declare a variable in B was to specify its storage type (auto or extern). Like this:

auto i;

This syntax still works in C and is equivalent to

int i;

because in C, the storage class defaults to auto, and the type defaults to int. I guess that every single program that originated in B and was ported to C was literally full of auto variables at that time.

C++03 no longer allows the C style implicit int, but it preserved the no-longer-exactly-useful auto keyword because unlike the implicit int, it wasn't known to cause any trouble in the syntax of C.

Jirka Hanika
  • 12,574
  • 3
  • 39
  • 68
1

The new meaning of the auto keyword in C++0x is described very nicely by Microsoft's Stephan T. Lavavej in a freely viewable/downloadable video lecture on STL found at MSDN's Channel 9 site here.

The lecture is worth viewing in its entirety, but the part about the auto keyword is at about the 29th minute mark (approximately).

Sabuncu
  • 4,529
  • 4
  • 37
  • 75