Есть ли причина использовать ключевое слово auto в C++03?
Вопрос
Примечание этот вопрос был первоначально опубликован в 2009 году, до ратификации C++ 11 и до определения значения
auto
Ключевое слово было радикально изменено.Представленные ответы относятся только к значению C++03auto
-- это указанный класс хранения -- а не значение C++11auto
- это автоматический вывод типа.Если вам нужен совет о том, когда использовать C++11auto
, этот вопрос не имеет отношения к этому вопросу.
Долгое время я думал, что нет смысла использовать static
Ключевое слово в C, поскольку переменные, объявленные за пределами области действия блока, были неявно глобальными.Затем я обнаружил, что объявление переменной как static
внутри области блока придаст ему постоянную продолжительность, а объявление его за пределами области действия блока (в области программы) даст ему область действия файла (доступ к которому возможен только в этом модуле компиляции).
Таким образом, у меня остается только одно ключевое слово, которое я (возможно) еще не до конца понимаю:А auto
ключевое слово.Есть ли что -то другое значение для этого, кроме «локальной переменной?» Что -нибудь, что это делает, не сделано для вас, где вы можете его использовать?Как auto
переменная ведет себя в области программы?Что за static auto
переменная в области файла?Имеет ли это ключевое слово какую-либо цель, кроме просто существую ради полноты?
Решение
auto
является спецификатором класса хранилища, static
, register
и extern
слишком.В объявлении можно использовать только один из этих четырех.
Локальные переменные (без static
) имеют автоматическую продолжительность хранения, что означает, что они живут с начала своего определения до конца своего блока.Ставить auto перед ними излишне, поскольку в любом случае это значение по умолчанию.
Я не знаю причин использовать его в C++.В старых версиях C, в которых было неявное правило int, вы могли использовать его для объявления переменной, например:
int main(void) { auto i = 1; }
Чтобы сделать синтаксис допустимым или устранить неоднозначность выражения присваивания в случае i
находится в области видимости.Но в C++ это все равно не работает (нужно указать тип).Забавно, что стандарт C++ пишет:
Объект, объявленный без спецификатора класса хранения в области видимости блока или объявленный как параметр функции, по умолчанию имеет автоматическую продолжительность хранения.[Примечание:следовательно, спецификатор auto почти всегда избыточен и используется нечасто;Одно из применений auto состоит в том, чтобы явно отличить оператор-объявление от оператора-выражения (6.8).— последнее примечание]
что относится к следующему сценарию, который может быть либо набором a
к int
или объявление переменной a
типа int
иметь лишние круглые скобки вокруг a
.Это всегда считается декларацией, поэтому auto
не добавил бы сюда ничего полезного, но добавил бы для человека.Но опять же, человеку было бы лучше убрать лишние круглые скобки вокруг a
, Я бы сказал:
int(a);
С новым смыслом auto
придя с C++0x, я бы не рекомендовал использовать его в коде со значением C++03.
Другие советы
В С++11 auto
имеет новое значение:он позволяет автоматически определить тип переменной.
Почему это когда-либо полезно?Давайте рассмотрим базовый пример:
std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
// Do stuff here
}
А auto
создается итератор типа std::list<int>::iterator
.
Это может значительно облегчить чтение очень сложного кода.
Другой пример:
int x, y;
auto f = [&]{ x += y; };
f();
f();
Там, auto
вывел тип, необходимый для хранения лямбда-выражения в переменной.В Википедии есть хорошо освещение по теме.
Ключевое слово auto в данный момент не имеет смысла.Вы совершенно правы в том, что он просто переопределяет класс хранения по умолчанию для локальной переменной, действительно полезной альтернативой является static
.
Оно имеет совершенно новый смысл в С++0x.Это дает вам некоторое представление о том, насколько это было бесполезно!
GCC имеет специальное использование auto
для вложенных функций - см. здесь.
Если у вас есть вложенная функция, которую вы хотите вызвать до ее определения, вам необходимо объявить ее с помощью auto
.
«auto» предположительно говорит компилятору самому решить, куда поместить переменную (в память или в регистр).Его аналогом является «регистр», который якобы сообщает компилятору, что нужно попытаться сохранить его в регистре.Современные компиляторы игнорируют оба, поэтому вам следует тоже.
Я использую это ключевое слово, чтобы явно документировать, когда для функции критично размещение переменной в стеке для процессоров на основе стека.Эта функция может потребоваться при изменении стека перед возвратом из функции (или процедуры обработки прерывания).В этом случае я заявляю:
auto unsigned int auiStack[1]; //variable must be on stack
И затем я получаю доступ за пределы переменной:
#define OFFSET_TO_RETURN_ADDRESS 8 //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;
Итак auto
Ключевое слово помогает документировать намерение.
По словам Страуструпа, в «Языке программирования C» (4-е издание, охватывающее C 11) использование «auto» имеет следующие основные причины (раздел 2.2.2) (слова Страуструпа цитируются):
1)
Определение находится в большом объеме, где мы хотим сделать тип четко видимым для читателей нашего кода.
С помощью auto и его необходимого инициализатора мы можем с первого взгляда узнать тип переменной!
2)
Мы хотим явно указать диапазон или точность переменной (например, double, а не float).
На мой взгляд, случай, который здесь подходит, выглядит примерно так:
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)
Используя «auto», мы избегаем избыточности и написания длинных имен типов.
Представьте себе какое-нибудь длинное имя типа из шаблонного итератора:
(код из раздела 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;
}
В старом компиляторе auto вообще было одним из способов объявления локальной переменной.Вы не можете объявлять локальные переменные в старых компиляторах, таких как Turbo C, без ключевого слова auto или чего-то подобного.
Новое значение ключевого слова auto в C++0x очень хорошо описано Стефаном Т. из Microsoft.Лавей в свободно просматриваемой и загружаемой видеолекции по STL, найденной на сайте MSDN Channel 9. здесь.
Лекцию стоит просмотреть целиком, но часть, посвященная ключевому слову auto, находится где-то на 29-й минуте (приблизительно).
Есть ли у слова «авто» какое-то другое значение, кроме «локальной переменной»?
Не в С++ 03.
Что-нибудь из того, что он делает, не делается для вас неявно, где бы вы ни захотели это использовать?
Ничего вообще, в C++03.
Как ведет себя автоматическая переменная в области программы?А как насчет статической автоматической переменной в области файлов?
Ключевое слово не допускается за пределами тела функции/метода.
Имеет ли это ключевое слово какую-либо цель [в C++03], кроме простого существования для полноты?
Удивительно, но да.Критерии проектирования C++ включали высокую степень обратной совместимости с C.Это ключевое слово было в языке C, и не было реальной причины запрещать его или переопределять его значение в C++.Итак, целью было на одну несовместимость с C меньше.
Имеет ли это ключевое слово какую-либо цель в C, кроме простого существования для полноты?
Я узнал одно только недавно:простота портирования древних программ от B.C произошел от языка B, синтаксис которого был очень похож на синтаксис C.Однако у Б не было вообще никаких типов.Единственный способ объявить переменную в B — указать тип ее хранения (auto
или extern
).Так:
авто я;
Этот синтаксис по-прежнему работает в C и эквивалентен
интервал я;
потому что в C класс хранения по умолчанию равен auto
, а тип по умолчанию — int
.Я предполагаю, что каждая программа, созданная на B и перенесенная на C, была буквально полна auto
переменные в то время.
C++03 больше не поддерживает неявный int в стиле C, но сохранил уже не совсем полезный тип. auto
ключевое слово, потому что, в отличие от неявного int, оно не вызывало никаких проблем в синтаксисе C.