Есть ли причина использовать ключевое слово auto для С++ 03?

Примечание этот вопрос был первоначально опубликован в 2009 году, прежде чем С++ 11 был ратифицирован и до того, как значение ключевого слова auto было радикально изменено. Приведенные ответы относятся только к значению С++ 03 auto - того, что указанный класс хранения, а не значение С++ 11 auto, - это автоматический вывод типа. Если вы ищете советы о том, когда использовать С++ 11 auto, этот вопрос не имеет отношения к этому вопросу.

В течение долгого времени я думал, что нет смысла использовать ключевое слово static в C, потому что переменные, объявленные за пределами области блока, были неявно глобальными. Затем я обнаружил, что объявление переменной как static в пределах области блока дало бы ей постоянную продолжительность, и объявление ее за пределами области блока (в области программы) дало бы ей область файл (к ней может быть доступ только в этом блоке компиляции).

Итак, это оставляет мне только одно ключевое слово, которое я (возможно) еще не понял полностью: auto. Есть ли другое значение, кроме "локальной переменной"? Все, что он делает, неявно делается для вас, где бы вы ни хотели его использовать? Как переменная auto ведет себя в области программы? Что из переменной static auto в области файлов? Имеет ли это ключевое слово какую-либо цель, кроме только существующей для полноты?

Ответ 1

auto - спецификатор класса хранения, static, register и extern тоже. Вы можете использовать только один из этих четырех в объявлении.

Локальные переменные (без static) имеют автоматическую продолжительность хранения, что означает, что они живут с самого начала их определения до конца их блока. Помещение авто перед ними избыточно, так как это по умолчанию.

Я не знаю, зачем использовать его в С++. В старых версиях C, которые имеют неявное правило int, вы можете использовать его для объявления переменной

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

Чтобы сделать его допустимым синтаксисом или disambiguate из выражения присваивания в случае, если i находится в области видимости. Но это все равно не работает на С++ (вам нужно указать тип). Довольно забавно, стандарт С++ пишет:

Объект, объявленный без спецификатора класса хранения в области блока или объявленный как параметр функции, по умолчанию имеет автоматическую продолжительность хранения. [Примечание: следовательно, авто-спецификатор почти всегда избыточен и не часто используется; одно использование auto заключается в том, чтобы явно отличить оператор объявления от выражения-выражения (6.8). -end note]

Это относится к следующему сценарию, который может быть либо отличным от a до int, либо объявлением переменной a типа int, имеющей избыточные круглые скобки вокруг a. Он всегда считается объявлением, поэтому auto не добавит ничего полезного здесь, но вместо этого будет для человека. Но, опять же, человеку было бы лучше снять лишние круглые скобки вокруг a, я бы сказал.

int(a);

С новым значением auto, прибывающим с С++ 0x, я бы отговорил использовать его с С++ 03, что означает код.

Ответ 2

В С++ 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 вывел тип, необходимый для хранения лямбда-выражения в переменной. Википедия имеет хороший охват по теме.

Ответ 3

Ключевое слово auto не имеет цели в настоящий момент. Вы совершенно правы, что он просто повторяет класс хранения по умолчанию для локальной переменной, и действительно полезной альтернативой является static.

Он имеет новый смысл в С++ 0x. Это дает вам некоторое представление о том, насколько бесполезно было!

Ответ 4

GCC имеет специальное использование auto для вложенных функций - см. здесь.

Если у вас есть вложенная функция, которую вы хотите вызвать до ее определения, вам нужно объявить ее с помощью auto.

Ответ 5

"auto" предположительно сообщает компилятору решить для себя, куда поместить переменную (память или регистр). Его аналогом является "регистр", который якобы сообщает компилятору попытаться сохранить его в регистре. Современные компиляторы игнорируют оба, поэтому вы тоже должны.

Ответ 6

Я использую это ключевое слово для явного документирования, когда это важно для функции, чтобы переменная была помещена в стек для процессоров на основе стека. Эта функция может потребоваться при изменении стека до возврата из функции (или процедуры обслуживания прерываний). В этом случае я заявляю:

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 помогает документировать намерение.

Ответ 7

Согласно "Страуструпу", в "языке программирования C" (4-е издание, охватывающем C 11), использование "авто" имеет следующие основные причины (раздел 2.2.2) (слова Stroustrup цитируются):

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

Ответ 8

В старом компиляторе auto был одним из способов объявить локальную переменную вообще. Вы не можете объявлять локальные переменные в старых компиляторах, таких как Turbo C без ключевого слова auto или некоторых таких.

Ответ 9

Новое значение ключевого слова auto в С++ 0x очень хорошо описано Microsoft Stephan T. Lavavej в свободно просматриваемой/загружаемой видео-лекции по STL, найденной на сайте 9 канала MSDN здесь.

Лекцию стоит посмотреть целиком, но часть ключевого слова auto примерно равна отметке 29-й минуты (приблизительно).

Ответ 10

Есть ли другое значение для "auto", кроме "локальной переменной"?

Не в С++ 03.

Все, что он делает, неявно делается для вас, где бы вы ни захотели его использовать?

Ничего, в С++ 03.

Как автоматическая переменная ведет себя в области программы? Что из статической автоматической переменной в области файлов?

Ключевое слово не допускается вне тела функции/метода.

Имеет ли это ключевое слово какую-либо цель [в С++ 03], отличную от существующей для полноты?

Удивительно, да. Критерии дизайна С++ включали высокую степень обратной совместимости с C. C, имеющим это ключевое слово, и не было реальной причины запретить его или переопределить его значение на С++. Таким образом, целью была одна менее несовместимость с C.

Имеет ли это ключевое слово какую-либо цель в C, отличную от существующей для полноты?

Я узнал об этом только недавно: легкость переноса старых программ из B. C эволюционировала из языка B, синтаксис которого был очень похож на синтаксис C. Однако у B не было никаких типов. Единственный способ объявить переменную в B - указать свой тип хранилища (auto или extern). Вот так:

auto i;

Этот синтаксис все еще работает в C и эквивалентен

int i;

поскольку в C класс хранения по умолчанию равен auto, а по умолчанию используется значение int. Я предполагаю, что каждая отдельная программа, которая возникла в B и была перенесена на C, была буквально заполнена переменными auto в то время.

С++ 03 больше не допускает неявный int в стиле C, но он сохранил ключевое слово auto, не содержащее больше времени, потому что, в отличие от неявного int, не было известно, что он вызывает какие-либо проблемы в синтаксисе С.