В настоящее время я читаю «Экспертное программирование на C - секреты Deep C» и только что пришел к этому:
Спецификатор класса хранения auto никогда не нужен. Это в основном имеет смысл для компилятора-писателя делая запись в таблице символов - там написано "это хранилище автоматически выделяется при входе в блок" (в отличие от статически выделяемого во время компиляции или динамически выделяемого в куче). Авто почти бесполезен для всех других программистов, поскольку его можно использовать только внутри функции, но объявления данных в функции имеют этот атрибут по умолчанию.
Я видел, что кто-то спрашивал о том же здесь, но у них нет ответа, а ссылка, данная в комментариях, только объясняет, почему в C есть такое ключевое слово, унаследованное от B, и различия с C++11 или до- С++11.
В любом случае я пишу, чтобы сосредоточиться на части, в которой говорится, что ключевое слово auto каким-то образом полезно при написании компилятора, но я не могу понять ни идею, ни связь с таблицей символов, может ли кто-нибудь помочь мне, пожалуйста?
Я действительно настаиваю на том, что спрашиваю только об использовании компилятора.
РЕДАКТИРОВАТЬ :
Чтобы уточнить, я задал этот вопрос, потому что хотел бы знать, есть ли пример кода, где auto может быть оправдано, потому что автор заявил, что будет, при написании компиляторов.
Здесь все дело в том, что я думаю, что понял auto (унаследовано от B, который был обязательным, бесполезным в C), но я не могу представить ни одного примера, когда его использование полезно (или, по крайней мере, не бесполезно).
Действительно кажется, что нет никакой причины использовать auto, но если у кого-то есть старый исходный код или что-то подобное, соответствующее цитируемым утверждениям, было бы интересно посмотреть.
@tadman Нет, меня просто интересовал процитированный абзац, потому что кажется, что auto (бесполезный в C) может быть полезен только в контексте написания компилятора, и я хотел бы знать, в каком именно случае.
Хотя это неплохой вопрос, который можно задать в общем смысле, это действительно открытый вопрос и в основном основанный на мнении, который здесь не по теме. Например, это относится к производителям компиляторов C, как к тем, кто реализует C, или в случае реализации компиляторов на C? Я бы интерпретировал это как первое.
Извините, если это не совсем подходит здесь, я в основном надеялся на вариант использования или пример, в котором использование auto может быть оправдано, потому что я не вижу его. Я предполагаю, что автор, вероятно, имел в виду реализацию компиляторов в C, потому что мы говорим о ключевом слове в C и о том, где его использовать.
Компиляторы выдают предупреждения, а также генерируют код, например, чтение неинициализированной переменной или возврат указателя на переменную, и для этого ему нужно знать, была ли она статической или автоматической.
Не нужно сожалеть. Есть много хороших вопросов, которые просто не подходят для этого формата Q/A. Это, вероятно, лучше адресовать тем, у кого гораздо больше опыта создания компиляторов, например, в какой-то группе или форуме для этого.
Помните, что в спецификации C есть много вещей, которые в то время казались отличной идеей, но позже оказалось, что они бесполезны. Есть много отзывов между командами по стандартизации C и C++, где C, вероятно, что-то вроде «о, да, auto означает, что «выясните это» имеет гораздо больше смысла, ну да ладно».
@WeatherVane Может быть, я неправильно понимаю, что вы имели в виду, но здесь я ожидаю знать, какие (если есть) примеры на C могут использовать auto.
Тот факт, что вам не нужно явно указывать auto, не означает, что компилятору не нужна эта информация, которая будет доступна через таблицу символов. Как говорится в вашей цитате: «компилятор-писатель, делающий запись в таблице символов».
Книга , из которой вы цитируете , кажется, 1994 года (или раньше). Так что да, может быть, это и было правдой 29 лет назад, но не сейчас.
В сторону: я считаю, что C23 будет переназначен auto, чтобы быть больше похожим на C++.
Спасибо @WeatherVane, я лучше понимаю, что вы имели в виду ранее,
@pmacfarlane Я знаю об этом, я думал, что это может быть не так в наши дни, но даже если это всего лишь старый редкий артефакт, я бы хотел только полностью понять кавычки, в конечном итоге увидев устаревший исходный код, чтобы понять это, это чисто теоретически.
«Я не могу представить ни одного примера, когда это полезно» — я замечаю, что автор книги утверждал, что это полезно, не объясняя, как и почему. Возможно, они ошибались или говорили о каких-то «тупых» компиляторах 80-х или начала 90-х, которым нужно было больше подсказок?
@DaveS Я внес изменения в свой пост, чтобы запросить код, если кто-то найдет старый код, демонстрирующий это.
@Chi_Iroh, я видел единственный случай использования auto, когда атрибуты объекта, такие как static, extern, auto, ...., были объединены в макрос. В случае, когда никакие атрибуты не нужны, макросу присваивается auto, а не ничего.
О, веселое использование! Мне нравится (теоретически, конечно).
Вы должны опубликовать «ответ автора» в качестве ответа ниже. Крайне не рекомендуется редактировать решение в самом вопросе.
Исправлено, спасибо





Насколько я могу судить за 40 с лишним лет программирования на C, включая работу с компилятором, ключевое слово auto было совершенно бесполезным в C в течение 50 лет.
Чтобы ответить на ваш точный вопрос, почему ключевое слово auto полезно для разработчиков компиляторов в C? Это совершенно бесполезно, им просто нужно проанализировать его как ключевое слово и реализовать его семантику как спецификатор класса хранения.
Кажется, это пережиток B , предшественника языка C, разработанного Кеном Томпсоном и Деннисом Ритчи в Bell Labs в конце шестидесятых и начале семидесятых. Я никогда не использовал B и сомневаюсь, что Питер, с которым я познакомился в 1984 году в Инрии, тоже.
auto используется в C++ для включения вывода типов, когда компилятор определяет тип переменной (с автоматическим сохранением или без него) по типу ее инициализатора.
С текущей тенденцией, подталкивающей к конвергенции общего подмножества для языков C и C++, к этому ключевому слову в C23 была добавлена новая семантика, созданная по образцу C++, но более ограниченная:
6.7.1 Спецификаторы класса памяти
autoможет появиться со всеми остальными, кромеtypedef;
autoдолжен появляться только в спецификаторах объявления идентификатора с областью действия файла или вместе с другими спецификаторами класса хранения, если тип должен быть выведен из инициализатора.Если
autoпоявляется с другим спецификатором класса хранения или если он появляется в объявлении в области файла, он игнорируется в целях определения продолжительности хранения связи. Затем он только указывает, что объявленный тип может быть выведен.
Вывод типа определяется как:
6.7.9 Вывод типа
Ограничения
1 Объявление, для которого выводится тип, должно содержать спецификатор класса хранения
auto.Описание
2 Для такого объявления, которое является определением объекта, init-declarator должен иметь одну из форм
прямой-декларатор = выражение-присваивания
прямой-декларатор = {выражение-присваивания}
прямой-декларатор = {выражение-присваивания,}Объявленный тип — это тип выражения присваивания после lvalue, преобразования массива в указатель или функции в указатель, дополнительно уточненного квалификаторами и измененного атрибутами, как они появляются в спецификаторах объявления, если таковые имеются. Если прямой декларатор не имеет форму идентификатора атрибута-спецификатора-последовательностиopt, возможно, заключенного в сбалансированные пары круглых скобок, поведение не определено.
На самом деле я видел, как его использовали в сложных тестах на собеседованиях, где кандидата просили выяснить, почему этот код не компилируется:
#include <stdio.h>
#include <string.h>
int main(void) {
char word[20];
int auto = 0;
while (scanf("%19s", line) == 1) {
if (!strcmp(word, "car")
|| !strcmp(word, "auto")
|| !strcmp(word, "automobile"))
auto++;
}
printf("cars: %d\n", auto);
return 0;
}
Ответ подтвержден, потому что он соответствует всему, что я видел в Интернете, и я совсем не удивлен, что даже такой опытный программист на C не видел утилиты для этого ключевого слова. А также тот факт, что вы получаете несколько голосов, усиливает этот момент.
Разве auto семантика C++ уже не реализована в C23?
@pmacfarlane У него нет точно семантики C++, но его можно использовать для вывода типа, как в auto x = foo(); в C23.
@Ted Я не эксперт в C++ (работаю над этим!), Но разве это не то же самое, что и в C++? Есть ли разница?
@pmacfarlane Это одно из применений auto, которое работает на обоих языках. В C++ их гораздо больше. Не все виды использования были бы невозможны в C, и если бы синтаксис C++ был разрешен в C для этих случаев, это сделало бы файлы заголовков, используемые как C, так и C++, действительно подверженными ошибкам.
@TedLyngmo: ИМХО, это грустный шаг - пытаться свести C к его дальнему родственнику.
@pmacfarlane: Боюсь, вы правы ... в C23 столько дерьма, что я пропустил это. Ответ изменен
@chqrlie Это породит легион новых вопросов SO, где люди путают свои типы, используя auto везде. Это очень ленивое решение, которое создает больше проблем, чем решает. Говоря это, мне нравится это в C++, потому что у него есть несколько очень подробных составных типов, которых нет в C.
Ключевое слово auto происходит из языка B, где оно было на самом деле очень полезным и позволяло отличать локальные имена от нелокальных (помечено ключевым словом extrn).
main()
{
extrn printf;
auto x;
x = 25;
printf('%d', x);
}
Когда язык B превратился в C, он сохранил высокую степень обратной совместимости. В B был в основном только один тип «ячейки», поэтому в C они ввели аннотации типов в качестве дополнительной функции. В C89 и ранее auto использовался для той же цели введения местных имен.
main()
{
extern printf();
auto x; /* type is int by default */
x = 42;
printf("%d", x);
}
После того, как фокус языка сместился в сторону обеспечения безопасности типов, потребность в спецификаторе auto полностью исчезла, поскольку наличие аннотации типа позволяло различать объявления локальных имен.
Ответ автора: Я только что отправил электронное письмо мистеру Ван дер Линдену, и вот что он сказал:
Да, я согласен с людьми, которые ответили на вопрос о переполнении стека. Я не знаю наверняка, потому что я никогда не использовал язык B, но мне кажется весьма правдоподобным, что «auto» попало в C, потому что оно было в B. Даже когда я профессионально занимался программированием ядра и компилятора на C в 1980-х, я никогда не видел кода, который я могу вспомнить, который использовал бы «авто». Ключевой вывод заключается в том, что ключевое слово auto не добавляет никакой дополнительной информации и поэтому является избыточным и ненужным. Было ошибкой перевести его на C!
Я также попрошу объяснить, что он имел в виду, говоря о написании компилятора и таблице символов здесь, следите за обновлениями, если вам интересно!
Какая у вас проблема с написанием компилятора?