Подтвердить что ты не робот

Почему разработчики языка С++ поддерживают повторное использование ключевых слов?

В чем главный аргумент в пользу повторного использования коротких ключевых слов (и добавления контекстно-зависимых значений) вместо добавления большего количества ключевых слов?

Это просто, что вы хотите избежать нарушения существующего кода, который уже может использовать новое ключевое слово, или есть более глубокая причина?

Новый "класс enum" в С++ 11 заставил меня задуматься об этом, но это общий вопрос дизайна языка.

4b9b3361

Ответ 1

Это просто то, что вы хотите избежать нарушения существующего кода, который уже может использовать новое ключевое слово, или есть более глубокая причина?

Нет, это причина.

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

Комитет C использует другой подход и добавляет новые ключевые слова, используя _Reserved имена, например. _Atomic, _Bool, а затем они добавляют новый заголовок (<stdatomic.h>, <stdbool.h>) с более приятным макросом, так что вы можете выбрать, включать ли заголовок для получения имени atomic или bool, но он не будет объявлен автоматически и не будет нарушать код, который уже используется с этими именами.

Комитет С++ не любит макросы и хочет, чтобы они были правильными ключевыми словами, поэтому либо повторно используйте существующие (например, auto), либо добавляйте зависящие от контекста "ключевые слова" (которые на самом деле не являются ключевыми словами, но являются "идентификаторы со специальным значением", поэтому их можно использовать для других вещей, таких как override), или использовать странные письма, которые вряд ли будут сталкиваться с кодом пользователя (например, decltype вместо широко поддерживаемого расширения typeof).

Ответ 2

Некоторые старые языки вообще не имели ключевых слов, в частности PL/1, где

IF IF=THEN THEN BEGIN;
  /* some more code */
END;

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

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

Также известно, что С++ медленно анализируется (в частности, поскольку стандартные заголовки, такие как <vector>, вытягивают десятки тысяч строк исходного кода и потому, что модули еще не находятся в С++ и потому что синтаксис сильно неоднозначен), поэтому сложность анализатора для обработки нового синтаксиса не является большой проблемой (разбор С++ всегда был ужасен). Например, сообщество GCC намного усложняется в отношении новых оптимизаций, чем для новых возможностей С++ (по-видимому, последние возможности стандартной библиотеки С++ требуют большой работы, чем синтаксический анализ нового синтаксиса), даже если переход с С++ 03 на С++ 11 был огромным прыжком и потребовал большой работы в интерфейсе С++. Это менее верно для прыжка с С++ 11 до С++ 14.

Некоторые другие языки (например, некоторые диалекты Lisp, такие как Общие Lisp и некоторые Scheme, где вы можете переопределить макрос let или if и макросы в homoiconic языки, подобные этим, очень разные, поскольку работают на AST, из необоснованной текстовой замены в C или С++...) позволяют переопределить существующие ключевые слова; читайте также о гигиенических макросах. Но это может затруднить понимание исходного кода несколькими месяцами позже.

Ответ 3

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

Ответ 4

Это просто то, что вы хотите избежать нарушения существующего кода, который уже может использовать новое ключевое слово, или есть более глубокая причина?

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

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

С другой стороны, в тех местах, где ранее был разрешен какой-либо идентификатор, добавление ключевого слова создает риск. Например:

  • struct H { my_type f; enum { g }; };: использование enum class, а не ключевое слово new, потому что любое новое слово можно ошибочно принять за начало объявления члена данных в этом контексте; только ключевое слово однозначно (в LL (1)), а введение нового может сломать код.
  • void h() { my_type f; auto x = g(); }: использование auto вместо нового ключевого слова связано с тем, что любое новое слово может столкнуться с существующим типом. Это удивительный выбор, поскольку он уже был ключевым словом, который можно использовать в этой позиции в C (по умолчанию для типа int), но его значение было изменено (оправдание было низкой вероятностью его использования).

Как уже упоминалось, языки могут быть разработаны без ключевых слов целиком (Haskell подходит довольно близко) или сделаны так, как можно легко вводить ключевые слова (например, если каждое объявление начинается с ключевого слова уже, а затем вводит новый ключевое слово не может столкнуться). Это так происходит, только C и С++, где это не сделано, и действительно многие языки C-типа.

Ответ 5

Ошибочный энтузиазм "меньше - больше". Считается (неправильно), что, используя меньшее количество ключевых слов, программистам нужно будет учиться меньше и может быть более продуктивным раньше. Но это только создает путаницу в синтаксисе.

"Реальные программисты Perl предпочитают визуально различать". ---- Ларри Уолл

Другими словами, используйте ключевое слово только для одной задачи.