LINUX.ORG.RU
ФорумTalks

Как вы думаете, препроцессор это удобно?

 , ,


0

1

На примере Си, часто препроцессор ругают за неявную типизированность и трудность при отладке макросов, я конечно не знаю как в других ЯП где есть препроцессор, но собственно в вашей практике, часто ли вы натыкались на какие-нибудь трудности в использовании препроцессора или наоборот большую часть оптимизации проводите в нем? (например define вместо inline).

★★★★★

Это просто разные подходы к разработке. Препроцессор хорош для всяких низкоуровневых системных языков. Прикладные языки имеют куда более удобные инструменты типа дженериков\шаблонов.

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

DawnCaster ★★
()
Последнее исправление: DawnCaster (всего исправлений: 1)

С какой целью интересуешься? Железные аргументы против препроцессора ты сам привёл, но всё равно спросил, значит ты хочешь чтобы кто-то тебе сказал что активно использует препроцессор и брат жив, и тогда у тебя будет аргумент положить на давно сложившиеся и общепризнанные практики в индустрии и говнякать на макросах потому что «у васи работает»?

Так-то лично я на трудности в использовании cpp не натыкался, потому что к великому счастью во всех кодбазах куда я коммичу он запрещён для любых нетривиальных вещей.

slovazap ★★★★★
()

Да вполне

(defun my-sin (a)
  (cos (- #.(/ pi 2)
          a)))
ados ★★★★★
()

По-сути - это два разных языка по цене одного. Например - чем тебе jinja не препроцессор? Плохо интегрирован с компилятором? Не стандартизирован? Убивает обратную совместимость? Ну это как бэ мелочи, было бы желание…

pon4ik ★★★★★
()

отдельный препроцессор — ну это Гэ
а такой как в Сях — это ваще Гэ

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

Bad_ptr ★★★★★
()

У препроцессора в C есть один важный плюс - макрос может быть «развёрнут» почти в любом месте (Например: внутри определения структуры). Если без этого можно легко обойтись, предпочитаю не пользоваться. В общем и целом стараюсь избегать где возможно.

anonymous-angler ★☆
()
Последнее исправление: anonymous-angler (всего исправлений: 1)
Ответ на: комментарий от Bad_ptr

Constexpr функции + шаблоны чем не компайлтайм программирование? Если ты про расширение, позволяющее менять синтаксис и лабать eDSL, обезьяны же взвоют. Им и так сложна!

filosofia
()
Ответ на: комментарий от filosofia

Проблема С++нутого метапрограммирования в том, что там у них «чистые функции» как в хаскеле, но даже в хаскеле есть IO, а там нет.

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

в общем равняться надо на лисповые макросы, которые всемогущи

Bad_ptr ★★★★★
()

неявную типизированность

Пример можно?

трудность при отладке макросов,

Обычно, сначала отлаживаю код, а потом делаю из куска копипасты тело макроса. Никаких проблем с отладкой при таком подходе не видел.

Но вот когда из имен каких-нибудь сущностей генерируются имена макросов/функций и вложенность макросов больше 2, - тогда да, отлаживать трудно бывает…

А в целом, - препроцессор нужен тчк. Хотя бы потому, что можно сделать так или так, что способствует снижению числа возможных ошибок.

shkolnick-kun ★★★★★
()
Последнее исправление: shkolnick-kun (всего исправлений: 3)
Ответ на: комментарий от shkolnick-kun

Если у вас возникает потребность в параллельных списках - у вас плохо определены структуры данных

cvs-255 ★★★★★
()

Осуждаю препроцессор. Там иногда такая магия встречается, что совсем странные штуки происходят. И даже если всё задокументировано это не значит что все разработчики осилили прочитать и помнить наизусть всё что есть в проекте, если он не hello world.

ЗЫ

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

Там иногда такая магия встречается, что совсем странные штуки происходят.

Это да.

все разработчики осилили прочитать и помнить наизусть всё что есть в проекте,

Нельзя так делать ни в коем случае, если не «хэлоу ворлд».

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

Например?

shkolnick-kun ★★★★★
()
Ответ на: комментарий от shkolnick-kun

Нельзя так делать ни в коем случае, если не «хэлоу ворлд».

Да, о чём и речь

Например?

Тут важно понимать, что я отделяю 2 задачи, первая нагенирировать автоматически реальный исполняемый код и 2 при помощи костылей нагенерировать исходный код, который потом будет собираться в исполняемый. От первого никуда не деться, он в явном или не явном виде будет всегда. А второго можно избежать, например, используя порождающие шаблоны проектирования и дженерики. Более того, единственный случай когда я в нормальном языке вижу однозначно оправданной кодогенерацию в виде генерации исходного кода, это когда всё очень сильно завязано на данных, которые есть в каком-то удобоваримом формате. И то только когда генерация идёт вместе с созданием ресурсов (те же текстурки для ускорения работы нагенерировать, если это позволяет алгоритм)

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Специально ужасный пример :-)

#define MIN(a,b) (a < b) ? a : b
#define A 123
#define B 11.1111
#define C 999999999
int main()
{
	printf("sizeof : %d\n",sizeof(A));
	printf("sizeof : %d\n",sizeof(B));
	printf("sizeof : %d\n",sizeof(C));
	printf("MIN : %d\n", MIN(A, B));
	printf("MIN : %d\n", MIN((C / 45), (A * 18.0)));
	return 0;
}



ex1.c:7:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
  printf("sizeof : %d\n",sizeof(A));
                   ~^
                   %ld
ex1.c:8:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
  printf("sizeof : %d\n",sizeof(B));
                   ~^
                   %ld
ex1.c:9:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
  printf("sizeof : %d\n",sizeof(C));
                   ~^
                   %ld
ex1.c:10:17: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
  printf("MIN : %d\n", MIN(A, B));
                ~^
                %f
ex1.c:11:17: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
  printf("MIN : %d\n", MIN((C / 45), (A * 18.0)));


sizeof : 4
sizeof : 8
sizeof : 4
MIN : 330175072
MIN : 330175072

splinter ★★★★★
() автор топика
Последнее исправление: splinter (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Если у тебя параллельные списки - значит на самом деле у тебя 1 список, в каждом элементе которого стоит пара (или более) величин. И значит так и надо описать структуры.

cvs-255 ★★★★★
()
Последнее исправление: cvs-255 (всего исправлений: 2)
Ответ на: комментарий от cvs-255

Нет.

В случае X-macro у меня есть:

  1. массив человекочитаемых имен (не важно сколько измерений) и, опционально, - в каждом элементе этого массива - набор каких-то лексем, которые можно использовать совместно с именами.

  2. несколько (как правило - больше двух) мест, где могут использоваться имена из массива и лексемы, к ним привязанные.

И ты не поверишь, но в одну структуру это не запихать, т.к. места, где мне нужно преобразовать массив имен в какие-то сущности, могут быть в разных областях или сегментах памяти, например:

  • в таблице векторов прерываний строго в определенном месте памяти программ
  • и переменные состояния этих обработчиков где-то в оперативной памяти,
  • плюс enum с айдишниками этих прерываний.

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

shkolnick-kun ★★★★★
()
Последнее исправление: shkolnick-kun (всего исправлений: 5)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.