Где используется ключевое слово C auto?

104

В студенческие годы я читал о autoключевом слове и со временем забыл, что это такое. Это определяется как:

определяет локальную переменную как имеющую локальное время жизни

Я никогда не обнаружил, что он где-то используется, действительно ли он используется, и если да, то где и в каких случаях?

Виджай
источник

Ответы:

90

autoэто модификатор типа static. Он определяет класс хранения переменной. Однако, поскольку значение по умолчанию для локальных переменных равно auto, обычно вам не нужно указывать его вручную.

На этой странице перечислены различные классы хранения в C.

Мехрдад Афшари
источник
13
Просто смотрел на это снова после того, как кто-то проголосовал за мой ответ. Вы говорите, что «обычно не нужно указывать это вручную». Я просто должен спросить: есть ли на самом деле обстоятельства, при которых auto можно указать, но не произойдет по умолчанию?
Jerry Coffin
2
@JerryCoffin Нет в C. В C ++ 11 он перепрофилирован, и вы можете использовать его для эффективного вывода типа локальной переменной.
Mehrdad Afshari
2
Одно из возможных применений - прямое объявление вложенных функций в GNU C - хотя это перехват исходного определения auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah 06
2
Ссылка на страницу устарела. Начиная с C11, есть также _Thread_localподробности: en.cppreference.com/w/c/language/storage_duration и stackoverflow.com/a/14289720/6557621
MCCCS
132

Если вы читали список часто задаваемых вопросов ( IAQ ), вы бы знали, что auto полезен в первую очередь для определения или объявления транспортного средства:

auto my_car;

Автомобиль, который постоянно припаркован на открытом воздухе:

extern auto my_car;

Для тех, у кого нет чувства юмора и кто хочет «только факты, мэм»: краткий ответ: нет никаких причин для использования autoвообще. Единственный раз, когда вам разрешено использовать, auto- это переменная, у которой уже есть autoкласс хранения, поэтому вы просто указываете что-то, что все равно произойдет. Попытка использовать autoлюбую переменную, у которой еще нет autoкласса хранения, приведет к тому, что компилятор отклонит ваш код. Я полагаю, если вы хотите получить техническую информацию, ваша реализация не обязательно должна быть компилятором (но это так), и теоретически она может продолжать компилировать код после выдачи диагностики (но это не так).

Небольшое дополнение от kaz :

А также есть:

static auto my_car;

который требует диагностики в соответствии с ISO C. Это правильно, потому что он заявляет, что автомобиль сломался. Диагностика проводится бесплатно, но выключение подсветки приборной панели обойдется вам в восемьдесят долларов. (Двадцать или меньше, если вы приобретете собственный USB-ключ для бортовой диагностики на eBay).

Вышеупомянутое extern auto my_carтакже требует диагностики, и по этой причине она никогда не запускается через компилятор, кроме как городским персоналом, которому поручено следить за парковкой.

Если вы видите много extern static auto ...кода в любой базе, значит, вы находитесь в плохом районе; немедленно ищите работу получше, пока все не превратилось в Rust.

Джерри Гроб
источник
@self .: ISO, похоже, не знает об «ISO 2011». Что, по вашему мнению, можно стандартизировать?
Jerry Coffin
6
Хорошо, что у меня во рту не было кофе, колы, стаут ​​или другой жидкости темного цвета. @JerryCoffin, ты бы должен был мне компьютерный экран, в таком случае. ЛУЧШИЙ ОТВЕТ!
Дэвид Хаммен
2
@Dan: Честно говоря, вам потребовалось «довольно много времени», чтобы прочитать 5 строк текста и добраться до той части, где говорится: «Короткий ответ в том, что вообще нет причин использовать авто»? Шутки в сторону? Учитывая комментарий, непосредственно предшествующий вашему, кажется, что по крайней мере некоторые люди считают его положительным вкладом.
Джерри Коффин
@JerryCoffin Я уже объяснил это, прочтите мой комментарий еще раз. Взгляд в прошлое - 20/20.
Дэн
2
Недавно я прошел через серьезный пожар (перекрыло две полосы движения), что говорит о необходимостиchar auto my_car;
совершенно
46

autoКлючевое слово бесполезно в языке Си. Это связано с тем, что до языка C существовал язык B, в котором это ключевое слово было необходимо для объявления локальных переменных. (B был преобразован в NB, который стал C).

Вот справочное руководство для B .

Как видите, руководство изобилует примерами, в которых autoиспользуется. Это потому, что нет intключевого слова. Требуется какое-то ключевое слово, чтобы сказать «это объявление переменной», и это ключевое слово также указывает, является ли оно локальной или внешней (по autoсравнению с extrn). Если вы не используете один или другой, у вас есть синтаксическая ошибка. То есть x, y;само по себе не декларация, а auto x, y;есть.

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

Из руководства очевидно, что устаревшее "неявное int" в C (возможность писать main() { ... }без каких-либо предварительных данных int) также исходит от B. Это еще одна функция обратной совместимости для поддержки кода B. Функции не имеют типа возвращаемого значения, указанного в B, потому что нет типов. Все - словом, как и во многих языках ассемблера.

Обратите внимание , как функция только может быть объявлена extrn putcharи тогда единственное , что делает его функция, идентификатор в использовании : он используется в выражении вызова функции , как putchar(x), и это то, что заставляет компилятор лечить , что бестиповое слово как указатель на функцию.

Каз
источник
25

В C auto- ключевое слово, указывающее, что переменная является локальной для блока. Поскольку это значение по умолчанию для переменных с блочной областью видимости, оно не требуется и используется очень редко (не думаю, что когда-либо видел его использование вне примеров в текстах, где обсуждается ключевое слово). Мне было бы интересно, если бы кто-нибудь мог указать на случай, когда использование autoбыло необходимо для получения правильного синтаксического анализа или поведения.

Однако в стандарте C ++ 11 autoключевое слово было «перехвачено» для поддержки вывода типа, когда тип переменной может быть взят из типа ее инициализатора:

auto someVariable = 1.5;   // someVariable will have type double

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

Майкл Берр
источник
1
«Переменная локальна для блока» - это совсем не так. Все переменные, объявленные в блоке, являются локальными для этого блока (относительно области видимости). Они могут быть связаны с другими переменными в программе, но объявление видно только в этом блоке. autoкасается класса хранения, который не имеет ничего общего с видимостью.
fuz 04
12

В старом компиляторе Aztec C все автоматические переменные можно было преобразовать в статические (для увеличения скорости адресации) с помощью переключателя командной строки.

Но в этом случае переменные, явно объявленные с помощью, autoбыли оставлены как есть. (Обязательно для рекурсивных функций, которые иначе не работали бы должным образом!)

рафнет
источник
7

autoКлючевое слово аналогично включение в Python с запятой, требовались от предыдущего языка ( B) , но разработчики поняли , что это было излишним , так как большинство вещей были auto.

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

Например, в B и 80-х C:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}
Михаил
источник
1

Ключевое слово Auto - это пример класса хранения (своего рода методы, которые определяют время жизни переменной и место хранения). У него есть поведение, при котором переменная, созданная с помощью этого ключевого слова, имеет продолжительность жизни (время жизни), находится только в фигурных скобках.

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          
Атул Шарма
источник
1

autoможет использоваться только для переменных с блочной областью видимости. extern auto int- это мусор, потому что компилятор не может определить, использует ли он внешнее определение или следует ли переопределить extern с помощью автоматического определения (также auto и extern - это совершенно разные сроки хранения, например static auto int, что также очевидно является мусором). Он всегда может интерпретировать его одним способом, но вместо этого предпочитает рассматривать его как ошибку.

Есть одна функция, которая autoдействительно обеспечивает, и это включение правила «все является int» внутри функции. В отличие от функции вне функции, где a=3интерпретируется как определение, int a =3потому что присваивания не существуют в области файла, a=3это ошибка внутри функции, поскольку, очевидно, компилятор всегда интерпретирует ее как присвоение внешней переменной, а не определение (даже если есть неты extern int aфорвардных деклараций в функции или в области файла), но спецификатор , как static, const, volatileили autoбудет означать , что это определение и компилятор принимает его в качестве определения, за исключением того, autoне имеет побочные эффекты других спецификаторов. auto a=3поэтому неявно auto int a = 3. По общему признанию,signed a = 3имеет тот же эффект и unsigned a = 3всегда представляет собой целое число без знака.

Также обратите внимание: « autoне влияет на то, будет ли объект помещен в регистр (если какой-то конкретный компилятор не обратит на это внимания, но это кажется маловероятным)»

Льюис Келси
источник
-1

Я уверен, что вы знакомы со спецификаторами класса хранения в C, такими как «extern», «static», «register» и «auto». Определение «auto» в значительной степени дается в других ответах, но вот возможное использование ключевого слова «auto», в котором я не уверен, но я думаю, что это зависит от компилятора. Видите ли, в отношении спецификаторов класса хранения есть правило. Мы не можем использовать несколько спецификаторов класса хранения для переменной. Вот почему статические глобальные переменные не могут быть извлечены. Следовательно, они известны только своему досье. Когда вы переходите к настройке вашего компилятора, вы можете включить флаг оптимизации для скорости. один из способов оптимизации компилятора: он ищет переменные без спецификаторов класса хранения, а затем делает оценку на основе доступности кэш-памяти и некоторых других факторов, чтобы увидеть, следует ли обрабатывать эту переменную с использованием спецификатора регистра или нет. Теперь, что, если мы хотим оптимизировать наш код для повышения скорости, зная, что конкретная переменная в нашей программе не очень важна, и мы не хотим, чтобы компилятор даже рассматривал ее как регистр. Хотя, если поставить auto, компилятор не сможет добавить спецификатор регистра в переменную, так как набирает "register auto int a;" ИЛИ "автоматическая регистрация int a;" вызывает ошибку использования нескольких спецификаторов класса хранения. Подводя итог, я подумал, что auto может запретить компилятору обрабатывать переменную как регистр посредством оптимизации. что, если мы хотим оптимизировать наш код для повышения скорости, зная, что конкретная переменная в нашей программе не очень важна, и мы не хотим, чтобы компилятор даже рассматривал ее как регистр. Хотя, если поставить auto, компилятор не сможет добавить спецификатор регистра в переменную, так как набирает "register auto int a;" ИЛИ "автоматическая регистрация int a;" вызывает ошибку использования нескольких спецификаторов класса хранения. Подводя итог, я подумал, что auto может запретить компилятору обрабатывать переменную как регистр посредством оптимизации. что, если мы хотим оптимизировать наш код для повышения скорости, зная, что конкретная переменная в нашей программе не очень важна, и мы не хотим, чтобы компилятор даже рассматривал ее как регистр. Хотя, если поставить auto, компилятор не сможет добавить спецификатор регистра в переменную, так как набирает "register auto int a;" ИЛИ "автоматическая регистрация int a;" вызывает ошибку использования нескольких спецификаторов класса хранения. Подводя итог, я подумал, что auto может запретить компилятору обрабатывать переменную как регистр посредством оптимизации. вызывает ошибку использования нескольких спецификаторов класса хранения. Подводя итог, я подумал, что auto может запретить компилятору обрабатывать переменную как регистр посредством оптимизации. вызывает ошибку использования нескольких спецификаторов класса хранения. Подводя итог, я подумал, что auto может запретить компилятору обрабатывать переменную как регистр посредством оптимизации.

Эта теория не работала для компилятора GCC, однако я не пробовал другие компиляторы.

Алиреза Миргасеми
источник