Почему использование препроцессора менее распространено в языках кроме C/C ++/ObjC?

Для Perl существует WWW:: Механизировать.

11
задан cdmckay 12 August 2009 в 21:56
поделиться

12 ответов

Я не знаю Objective-C, поэтому мой ответ будет о противопоставлении использования препроцессора в C и C ++.

Препроцессор изначально был необходим для C по нескольким причинам. Если я правильно помню, изначально в C не было констант, поэтому #define был необходим, чтобы избежать магических чисел. До 1999 г. в C не было встроенных функций, поэтому снова #define использовался для создания макросов или «псевдофункций», чтобы сэкономить накладные расходы на вызов функции, сохраняя при этом структуру кода. C также не имеет полиморфизма времени выполнения или компиляции, поэтому для условной компиляции потребовались #ifdef . Компиляторы обычно были недостаточно умны, чтобы оптимизировать недостижимый код, поэтому, опять же, для вставки кода отладки или диагностики использовались #ifdef .

Использование препроцессора в C ++ является возвратом к C и обычно не одобряется. Возможности языка, такие как константы, встроенные функции и шаблоны, могут использоваться в большинстве ситуаций, когда в C вы использовали бы препроцессор.

Некоторые случаи, когда использование препроцессора в C ++ допустимо или даже необходимо, включают защиту файлов заголовков, чтобы предотвратить включение одного и того же заголовка несколько раз, #ifdef __cplusplus для используйте один и тот же заголовок для C и C ++, __ FILE __ и __ LINE __ для ведения журнала и некоторых других.

Препроцессор также часто используется для определений платформы, хотя C ++ Gotchas Стивена Дьюхерста советует иметь отдельные каталоги include для определений платформы,

14
ответ дан 3 December 2019 в 01:04
поделиться

Причина, по которой вы не видите препроцессор, используемый в Java, C # или Scala, заключается в том, что в этих языках его явно нет.

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

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

11
ответ дан 3 December 2019 в 01:04
поделиться

Я не согласен с существующим консенсусом, согласно которому этот cpp не нужен в современных языках. У меня много случаев, когда у меня есть 3 немного разных версии одной и той же программы, и я хочу иметь возможность внести кучу изменений для каждой версии. С помощью CPP я могу поместить их все в блоки #if #else и определить #if в строке компиляции. в Java мне нужно создать какой-то статический глобальный объект и инициализировать его во время компиляции. Я так и не смог заставить это работать должным образом.

2
ответ дан 3 December 2019 в 01:04
поделиться

Каждому языку нужен механизм для отдельной компиляции . В идеале язык отличает интерфейсы от реализаций, а модуль зависит только от интерфейсов модулей, которые он экспортирует. (См., Например, Ada, Clu, Modula и т. Д.)

C не имеет языковых конструкций для интерфейсов или реализаций. Поскольку жизненно важно, чтобы разные файлы .c совместно использовали единое представление интерфейсов, дисциплина программирования эволюционировала путем помещения объявлений (т. Е. Интерфейсов) в файлы .h и совместного использования этих объявлений / интерфейсов с использованием текстового включения ( #include ) . В принципе, можно обойтись без #define и #ifdef , но с #include нельзя.

В настоящее время разработчики языков понимают, что включение текста недопустимо управлять железной дорогой, поэтому языки, как правило, работают либо с отдельно скомпилированными интерфейсами (Ada, Modula, OCaml), либо с интерфейсами, созданными компилятором (Haskell), либо с динамическими системами, гарантирующими согласованность интерфейса (Java, Smalltalk). С таким механизмом нет необходимости в препроцессоре и по множеству причин не иметь его (вспомните анализ исходного кода и отладку ).

9
ответ дан 3 December 2019 в 01:04
поделиться

Поскольку дизайн и цели этих языков не совпадают.

C был построен с учетом препроцессора как мощный инструмент, он использовался для реализации очень простых вещей (таких как защита включения), и разработчики могли использовать его либо для оптимизации своего кода с помощью макросов, либо для включения / исключения определенных блоков кода в дополнение к другим вещам. C ++ унаследовал большинство идиом C, макросы больше не используются для повышения скорости (потому что был введен встроенный), но он все еще используется для множества вещей, см. Сообщение Для чего нужны макросы препроцессора?

4
ответ дан 3 December 2019 в 01:04
поделиться

Потому что и Гослинг, и Хейлсберг понимают опасности и технический долг, связанный с неправильным использованием предварительной обработки!

3
ответ дан 3 December 2019 в 01:04
поделиться

В современных языках препроцессор включен в сам язык! Для C ++ препроцессор нужен только для управления модулями и условного включения, например, что очень полезно.

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

1
ответ дан 3 December 2019 в 01:04
поделиться

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

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

0
ответ дан 3 December 2019 в 01:04
поделиться

Вам следует внимательнее присмотреться к Perl. Perl поддерживает исходные фильтры , которые в основном представляют собой специальные препроцессоры Perl, написанные на Perl :)

0
ответ дан 3 December 2019 в 01:04
поделиться

Java была разработана таким образом, чтобы избежать некоторых функций, которые затрудняют использование C ++.

C # копирует (или наследует) большую часть проектных решений от Java.

Программирование более высокого уровня. языки избегают такого рода артефактов низкого уровня.

0
ответ дан 3 December 2019 в 01:04
поделиться

Препроцессор в C и C ++ имеет две разные функции

  • , объединяющие файлы в процессе сборки - languages как Java et al. имеют свои собственные механизмы, такие как импорт

  • для выполнения текстовых замен - это все еще необходимо в C, но C ++ может делать это (по большей части) лучше, используя шаблоны

Так что и C, и C ++ нуждаются в этом для первого из них, но C ++ может отбросить его для второго, хотя он может быть полезен даже в C ++ - см. этот вопрос от сегодняшнего дня.

1
ответ дан 3 December 2019 в 01:04
поделиться

Предварительная обработка очень, очень распространена в мире Java. Он используется для компенсации отсутствия в языке адекватных встроенных средств абстракции, что в противном случае привело бы к бесконечному копированию и вставке шаблонного кода.

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

2
ответ дан 3 December 2019 в 01:04
поделиться