Почему ключевое слово auto полезно для разработчиков компиляторов в C?

В настоящее время я читаю «Экспертное программирование на C - секреты Deep C» и только что пришел к этому:

Спецификатор класса хранения auto никогда не нужен. Это в основном имеет смысл для компилятора-писателя делая запись в таблице символов - там написано "это хранилище автоматически выделяется при входе в блок" (в отличие от статически выделяемого во время компиляции или динамически выделяемого в куче). Авто почти бесполезен для всех других программистов, поскольку его можно использовать только внутри функции, но объявления данных в функции имеют этот атрибут по умолчанию.

Я видел, что кто-то спрашивал о том же здесь, но у них нет ответа, а ссылка, данная в комментариях, только объясняет, почему в C есть такое ключевое слово, унаследованное от B, и различия с C++11 или до- С++11. В любом случае я пишу, чтобы сосредоточиться на части, в которой говорится, что ключевое слово auto каким-то образом полезно при написании компилятора, но я не могу понять ни идею, ни связь с таблицей символов, может ли кто-нибудь помочь мне, пожалуйста? Я действительно настаиваю на том, что спрашиваю только об использовании компилятора.

РЕДАКТИРОВАТЬ : Чтобы уточнить, я задал этот вопрос, потому что хотел бы знать, есть ли пример кода, где auto может быть оправдано, потому что автор заявил, что будет, при написании компиляторов.

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

Действительно кажется, что нет никакой причины использовать auto, но если у кого-то есть старый исходный код или что-то подобное, соответствующее цитируемым утверждениям, было бы интересно посмотреть.

Какая у вас проблема с написанием компилятора?

tadman 21.06.2023 23:28

@tadman Нет, меня просто интересовал процитированный абзац, потому что кажется, что auto (бесполезный в C) может быть полезен только в контексте написания компилятора, и я хотел бы знать, в каком именно случае.

Chi_Iroh 21.06.2023 23:29

Хотя это неплохой вопрос, который можно задать в общем смысле, это действительно открытый вопрос и в основном основанный на мнении, который здесь не по теме. Например, это относится к производителям компиляторов C, как к тем, кто реализует C, или в случае реализации компиляторов на C? Я бы интерпретировал это как первое.

tadman 21.06.2023 23:30

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

Chi_Iroh 21.06.2023 23:34

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

Weather Vane 21.06.2023 23:34

Не нужно сожалеть. Есть много хороших вопросов, которые просто не подходят для этого формата Q/A. Это, вероятно, лучше адресовать тем, у кого гораздо больше опыта создания компиляторов, например, в какой-то группе или форуме для этого.

tadman 21.06.2023 23:37

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

tadman 21.06.2023 23:38

@WeatherVane Может быть, я неправильно понимаю, что вы имели в виду, но здесь я ожидаю знать, какие (если есть) примеры на C могут использовать auto.

Chi_Iroh 21.06.2023 23:38

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

Weather Vane 21.06.2023 23:40

Книга , из которой вы цитируете , кажется, 1994 года (или раньше). Так что да, может быть, это и было правдой 29 лет назад, но не сейчас.

pmacfarlane 21.06.2023 23:42

В сторону: я считаю, что C23 будет переназначен auto, чтобы быть больше похожим на C++.

pmacfarlane 21.06.2023 23:47

Спасибо @WeatherVane, я лучше понимаю, что вы имели в виду ранее,

Chi_Iroh 21.06.2023 23:48

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

Chi_Iroh 21.06.2023 23:48

«Я не могу представить ни одного примера, когда это полезно» — я замечаю, что автор книги утверждал, что это полезно, не объясняя, как и почему. Возможно, они ошибались или говорили о каких-то «тупых» компиляторах 80-х или начала 90-х, которым нужно было больше подсказок?

Dave S 21.06.2023 23:49

@DaveS Я внес изменения в свой пост, чтобы запросить код, если кто-то найдет старый код, демонстрирующий это.

Chi_Iroh 21.06.2023 23:55

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

chux - Reinstate Monica 22.06.2023 00:26

О, веселое использование! Мне нравится (теоретически, конечно).

Chi_Iroh 22.06.2023 00:39

Вы должны опубликовать «ответ автора» в качестве ответа ниже. Крайне не рекомендуется редактировать решение в самом вопросе.

HolyBlackCat 22.06.2023 00:44

Исправлено, спасибо

Chi_Iroh 22.06.2023 00:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
19
72
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Насколько я могу судить за 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 не видел утилиты для этого ключевого слова. А также тот факт, что вы получаете несколько голосов, усиливает этот момент.

Chi_Iroh 21.06.2023 23:53

Разве auto семантика C++ уже не реализована в C23?

pmacfarlane 22.06.2023 00:10

@pmacfarlane У него нет точно семантики C++, но его можно использовать для вывода типа, как в auto x = foo(); в C23.

Ted Lyngmo 22.06.2023 00:15

@Ted Я не эксперт в C++ (работаю над этим!), Но разве это не то же самое, что и в C++? Есть ли разница?

pmacfarlane 22.06.2023 00:17

@pmacfarlane Это одно из применений auto, которое работает на обоих языках. В C++ их гораздо больше. Не все виды использования были бы невозможны в C, и если бы синтаксис C++ был разрешен в C для этих случаев, это сделало бы файлы заголовков, используемые как C, так и C++, действительно подверженными ошибкам.

Ted Lyngmo 22.06.2023 00:24

@TedLyngmo: ИМХО, это грустный шаг - пытаться свести C к его дальнему родственнику.

chqrlie 22.06.2023 00:34

@pmacfarlane: Боюсь, вы правы ... в C23 столько дерьма, что я пропустил это. Ответ изменен

chqrlie 22.06.2023 00:39

@chqrlie Это породит легион новых вопросов SO, где люди путают свои типы, используя auto везде. Это очень ленивое решение, которое создает больше проблем, чем решает. Говоря это, мне нравится это в C++, потому что у него есть несколько очень подробных составных типов, которых нет в C.

pmacfarlane 22.06.2023 00:43

Ключевое слово 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!

Я также попрошу объяснить, что он имел в виду, говоря о написании компилятора и таблице символов здесь, следите за обновлениями, если вам интересно!

Другие вопросы по теме