在 C + + 03中使用‘ auto’关键字有什么原因吗?

注意 这个问题最初是在2009年发布的,在 C + + 11被批准之前,在 auto关键字的含义被彻底改变之前。所提供的答案与 auto的 C + + 03含义有关—— auto是指定的存储类——而不是 auto的 C + + 11含义—— auto是自动类型推导。如果您正在寻求关于何时使用 C + + 11 auto的建议,那么这个问题与该问题无关。

在很长一段时间里,我认为没有理由在 C 中使用 static关键字,因为在 block-scope 之外声明的变量是隐式全局的。然后我发现,在 block-scope 中声明一个变量为 static会给它一个永久的持续时间,而在 block-scope 之外(在 program-scope 中)声明它会给它一个 file-scope (只能在那个编译单元中访问)。

因此,我只剩下一个关键字,我(可能)还没有完全理解: auto关键字。除了“局部变量”还有别的意思吗?无论你想在哪里使用它,它所做的任何事情都不是默认为你做的?auto变量在程序范围内是如何工作的?文件范围内的 static auto变量怎么样?这个关键字除了 只是为了完整而存在还有其他用途吗?

71137 次浏览

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!

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.

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

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.

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.

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

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.

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.

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;
}

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.