LINUX.ORG.RU

Метапрограммирование на препроцессоре

 , , , , санитары


1

6

Привет, ЛОР!

В принципе, я считаю, Rust больше не нужен. В Си наконец завезли не только сабж, но и реализацию алгебраических типов да с паттерн матчингом на нём! Ну и там ООП с интерфейсами, вот это вот всё. Примеры кода ниже.

Факториал в функциональном стиле:

#define factorial(n)          ML99_natMatch(n, v(factorial_))
#define factorial_Z_IMPL(...) v(1)
#define factorial_S_IMPL(n)   ML99_mul(ML99_inc(v(n)), factorial(v(n)))

ML99_ASSERT_EQ(factorial(v(4)), v(24));

Алгебраические типы:

#include <datatype99.h>

datatype(
    BinaryTree,
    (Leaf, int),
    (Node, BinaryTree *, int, BinaryTree *)
);

int sum(const BinaryTree *tree) {
    match(*tree) {
        of(Leaf, x) return *x;
        of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
    }

    return -1;
}

Интерфейсы (почти как трейты в Rust):

#include <interface99.h>

#include <stdio.h>

#define Shape_IFACE                      \
    vfunc( int, perim, const VSelf)      \
    vfunc(void, scale, VSelf, int factor)

interface(Shape);

typedef struct {
    int a, b;
} Rectangle;

int  Rectangle_perim(const VSelf) { /* ... */ }
void Rectangle_scale(VSelf, int factor) { /* ... */ }

impl(Shape, Rectangle);

typedef struct {
    int a, b, c;
} Triangle;

int  Triangle_perim(const VSelf) { /* ... */ }
void Triangle_scale(VSelf, int factor) { /* ... */ }

impl(Shape, Triangle);

void test(Shape shape) {
    printf("perim = %d\n", VCALL(shape, perim));
    VCALL(shape, scale, 5);
    printf("perim = %d\n", VCALL(shape, perim));
}

Я считаю, на этом все попытки убить Сишечку можно закапывать. Ссылка: https://github.com/hirrolot/metalang99

★★★★★

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

А мутабельные переменные можно создавать?
Вот это была бы бомба.
А так, что сишные макросы, что плюсовые темплейты, не способны даже счётчик вызовов функции/созданных объектов создать в компайлтайме.

Bad_ptr ★★★★★
()

Факториал в функциональном стиле:

Чуть-чуть изменяем пример (4 → 4 + 1):

#include <metalang99.h>

#define factorial(n)          ML99_natMatch(n, v(factorial_))
#define factorial_Z_IMPL(...) v(1)
#define factorial_S_IMPL(n)   ML99_mul(ML99_inc(v(n)), factorial(v(n)))

ML99_ASSERT_EQ(factorial(v(4 + 1)), v(24)); // (!)
Компиятор зависает, отжирая всё больше и больше памяти (!!!), приходит OOM killer либо systemd-oomd, либо система зависает.

Алгебраические типы:

Чуть-чуть изменяем пример, чтобы в случае tree == NULL обходил другое дерево:

#include <datatype99.h>

datatype(
    BinaryTree,
    (Leaf, int),
    (Node, BinaryTree *, int, BinaryTree *)
);

int sum(const BinaryTree *tree) {
    BinaryTree zero = {.tag = LeafTag, .data = {0}}; // (!)
    match(tree ? *tree : zero) {                     // (!)
        of(Leaf, x) return *x;
        of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
    }

    return -1;
}

Не компилируется:

In file included from ../metalang99/include/metalang99/gen.h:21,
                 from ../metalang99/include/metalang99.h:12,
                 from ./datatype99.h:30,
                 from foo.c:1:
foo.c: In function ‘sum’:
./datatype99.h:244:84: error: lvalue required as unary ‘&’ operand
  244 |     ML99_INTRODUCE_NON_NULL_PTR_TO_STMT(void, datatype99_priv_matched_val, (void *)&(val)) \
      |                                                                                    ^
../metalang99/include/metalang99/stmt.h:162:5: note: in definition of macro ‘ML99_PRIV_SHADOWS’
  162 |     __VA_ARGS__                                                                                    \
      |     ^~~~~~~~~~~
./datatype99.h:244:5: note: in expansion of macro ‘ML99_INTRODUCE_NON_NULL_PTR_TO_STMT’
  244 |     ML99_INTRODUCE_NON_NULL_PTR_TO_STMT(void, datatype99_priv_matched_val, (void *)&(val)) \
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./datatype99.h:41:27: note: in expansion of macro ‘match99’
   41 | #define match(val)        match99(val)
      |                           ^~~~~~~
foo.c:11:5: note: in expansion of macro ‘match’
   11 |     match(tree ? *tree : zero) {
      |     ^~~~~

Интерфейсы (почти как трейты в Rust):

Чуть-чуть изменяем пример (вместо переменной передаём в VCALL compound literal, который имеет точно такой же тип):

#include <interface99.h>

#include <stdio.h>

#define Shape_IFACE                      \
    vfunc( int, perim, const VSelf)      \
    vfunc(void, scale, VSelf, int factor)

interface(Shape);

typedef struct {
    int a, b;
} Rectangle;

int  Rectangle_perim(const VSelf) { /* ... */ }
void Rectangle_scale(VSelf, int factor) { /* ... */ }

impl(Shape, Rectangle);

typedef struct {
    int a, b, c;
} Triangle;

int  Triangle_perim(const VSelf) { /* ... */ }
void Triangle_scale(VSelf, int factor) { /* ... */ }

impl(Shape, Triangle);

void test(void) {                                              // (!)
    Rectangle rect = {.a = 3, .b = 4};                         // (!)
    VCALL(                                                     // (!)
        (Shape) {.self = &rect, .vptr = &Rectangle_Shape_impl}, // (!)
        scale,                                                 // (!)
        5);                                                    // (!)
}
Не компилируется:
In file included from bar.c:1:
bar.c: In function ‘test’:
./interface99.h:251:10: error: expected ‘}’ before ‘)’ token
  251 |     ((obj).vptr->IFACE99_PRIV_VCALL_OVERLOAD(__VA_ARGS__)((obj).self, __VA_ARGS__))
      |          ^
[слишком много выхлопа, остальное не привожу]

shdown
()
Последнее исправление: shdown (всего исправлений: 3)

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

и ржавчина тоже не нужна, как я всегда и говорила. таких недоязычков было навалом за много лет. все они канули в Лету.

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

Компиятор зависает, отжирая всё больше и больше памяти (!!!), приходит OOM killer либо systemd-oomd, либо система зависает.

Ну, да? Си – это не для слабых духом. Тут нужен мощный комп. У меня вот 128 гигов памяти и это минимум, нужный для программирования на Си.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от a1ba

Так автор этого вроде был на ЛОРе.

Знаешь, я даже ни на секунду не удивлён. ЛОР славен свой популяцией отборных шизофреников. Это всё синяя тема – она сводит людей с ума!

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

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

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

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

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

Ну вот скомпилируй код, который @shdown приложил.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Там, если чо, для компиляции нужно два других репозитория с гитхаба выкачать, datatype99 и interface99. Они упомянуты в README.

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

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

а если хотите извращений - берёте плюсы последнего разлива и вперёд. там подобного навалом. можно извращаться сколько влезет. но для реальной работы и с плюсами это всё тоже в 99.99% не нужно.

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

так я не псих какой-то, чтобы такое писать и компилить.

Вообще насрать. Это код на Си? Это код на Си. Ты можешь его скомпилировать на эмбеддеде с мизерными ресурсами? Нет, не можешь. Всё, вопрос закрыт.

а для писания реального софта эти извращения не нужны. поэтому для работы с Си не нужны никакие громадные ресурсы. достаточно даже самого слабенького офисного компа.

Особенно когда ты ядерный разработчик и тебе надо прогонять сборку ядра плюс тесты. Или ведро – это какой-то нереальный софт? Или оно не на Си? А с тем, что твои хелловорлды можно на Raspberry Pi первой версии гонять, никто не спорит.

а если хотите извращений - берёте плюсы последнего разлива и вперёд. там подобного навалом. можно извращаться сколько влезет. но для реальной работы и с плюсами это всё тоже в 99.99% не нужно.

У меня был вполне реальный рабочий проект на плюсах, где один файл не собирался на 32-битных системах, потому что 4G памяти не хватало. Спасибо Boost и такой-то матери. А сервисом пользовались десятки тысяч людей каждый день, так что реальнее просто некуда.

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

для писания реального софта эти извращения не нужны

https://lwn.net/Articles/983965/

Речь про ядро линукса:

But, then, Arnd Bergmann observed that the time required to compile the kernel had grown considerably in recent releases, and that the preprocessor had a lot to do with it; one file took a full 15 seconds just to get through the preprocessor stage. The problem came down to a single line of code in arch/x86/xen/setup.c

Even if one expects a large expansion, though, the actual amount may lead to significant eyebrow elevation: the single line of code shown above expands to 47MB of preprocessor output. Bergmann explained this result this way:

It nests min() multiple levels deep with the use of min3(), and each one expands its argument 20 times times now (up from 6 back in linux-6.6). This gets 8000 expansions for each of the arguments, plus a lot of extra bits with each expansion. PFN_DOWN(MAXMEM) contributes a bit to the initial size as well.

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

ядро прекрасно работало и собиралось без этого ненужно. пришли какие-то кукаретики и начали портить код, как всегда.

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

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от hateyoufeel

так мне-то зачем? мне xen не нужен.

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

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

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

в ядре надо отключать всё ненужное при сборке. тогда оно будет компилиться быстро и будет жрать очень мало ресурсов

Ты уже отключила макросы min/max в ядре? Сыр-бор весь из-за них, в коде Xen оно просто выстрелило.

Пока что все твои послания тут выглядят как «делойти харашо, плоха ни делойти!»

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

Вот что-то не обходятся, как видишь. Только ты можешь спасти лялекс от терминальной стадии ожирения!

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

min/mах как макросы использовать не нужно. есть операторы сравнения и оператор ?:. и тем более не нужны уродцы типа «min3». люди уже совсем отупели и пишут всякую чушь. поэтому ещё раз: гнать кукаретиков от разработки стандартов ссаными тряпками. чтобы подобных извращений не существовало в принципе. а средств языка вполне хватает на то, чтобы пистать быстро компилируемый код без оверкилла.

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

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

min/mах как макросы использовать не нужно.

Отлично же! Ждём от тебя патчей в LKML!

поэтому ещё раз: гнать кукаретиков от разработки стандартов ссаными тряпками

Так в стандарте min/max и нет. Их по проектам ручками копипастят.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

зачем? если оно будет мешать мне, я у себя пропатчу. лезть в апстрим я не стану. мне это ничего не даст, кроме потерянного времени.

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

Так в стандарте min/max и нет. Их по проектам ручками копипастят.

тогда тем более надо по рукам надавать тем, кто это бездумно везде тащит. тем более, что сам язык позволяет это не использовать, а использовать стандартные методы сравнения. пусть с ними разбираются Линус и Кроа-Хартман.

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

Ладно, это всё не важно. Писечка дискуссии в том, что твоё утверждение про «я могу писать на Си и компилировать программы даже на каком-нибудь эмбеддеде с мизерными ресурсами» является либо ошибочным, либо откровенной ложью. Выше привели пример макроса из ядра, который с мизерными ресурсами не скомпилируется (47 мегабайт выхлопа лол), и это не какой-то изощрённый эзотерический майндфак, а вполне реальный широкоиспользуемый проект.

тогда тем более надо по рукам надавать тем, кто это бездумно везде тащит

Кому надо? Тебе? Ты и надавай. Можешь с Торовалтоса начать.

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

есть операторы сравнения и оператор ?:

Их очень удобно использовать с __builtin_expect. Очень!
Ты и likely/unlikely не используешь?

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

Ты и likely/unlikely не используешь?

нет, если это не какой-то явный случай и если софтина вообще не работает ни с каким вводом-выводом. и да, это не даёт существенного ускорения для абсолютного большинства софта, потому что скорость теряется не на ветвлении с if'ами, а на работе периферии. а современные процы один фиг просчитывают оба варианта ветвления, так что и на электричестве ты таким образом тоже не сэкономишь. а если ты методом отважного пердолинга сэкономишь 10 наносекунд при работе обычного софта, то никто тебе спасибо не скажет.

а что там кому удобно-неудобно - это другой вопрос. если это порождает проблемы, вопрос про удобство вообще не рассматривается.

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

для писания реального софта эти извращения не нужны

Вот это утверждение ложно, как было мной показано. Имейте мужество признать свою ошибку. Касательно вашего тезиса «Торвальдс хороший, бояре плохие» — если Торвальдс был против макросов min()/max(), он бы их тупо запретил.

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

нет, не показано. показан был кусок говнокода, который почему-то просмотрели. а надо было сразу по рукам бить палкой.

я ещё раз говорю: не пишите говнокод и будет у вас всё в ажуре.

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

нет, не ошибочным. я много лет это делала и делаю.

Это не значит, что любой код на Си можно компилировать на ембеддеде. Это только значит, что твои хелловорлды можно. А серьёзные проекты типа ядра ОС – не факт.

hateyoufeel ★★★★★
() автор топика

«liberate tuteme ex enferis» (c) Сквозь горизонт - сцена с глазами.

как это развидеть теперь…

necromant ★★
()
Ответ на: комментарий от dataman

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

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

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

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

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

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

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

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

Какие навороты-то? Библиотечка по ссылке реализована на препроцессоре Си, для неё в компиляторах ничего специально не добавляли.

Блин, надо рейтинг шизофреников тут составить.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Так себя же придется в него включать :)

cobold ★★★★★
()
Ответ на: комментарий от hateyoufeel

У меня был вполне реальный рабочий проект на плюсах, где один файл не собирался на 32-битных системах, потому что 4G памяти не хватало. Спасибо Boost и такой-то матери. А сервисом пользовались десятки тысяч людей каждый день, так что реальнее просто некуда.

Но это же дичь. Ты так пишешь, как будто это нормально. То, что метаязык в С++ сделан максимально ужасно и вообще по сути появился в какой-то мере случайно - это же известный факт. Этого надо стыдиться, а не приводить в пример.

Вообще все эти средства метапрограммирования надо сравнивать с кодогенерацией. Вот представь себе кодогенератор, который бы генерировал примерно то же, что генерирует компилятор, разворачивая шаблоны в этом твоём файле. Только написанный не на метаязыке С++, а, для простоты. на обычном С++. Просто выплёвывает текст программы (с простой структурой), которую уже потом будет компилировать дальше компилятор. Вот - этот кодогенератор - он будет жрать 4G памяти? Или он будет жрать 100KB памяти? Я думаю, второе. По крайней мере в моей практике кодогенераторы были и ни один из них не был таким ресурсоёмким. Я вообще плохо представляю себе оптимально написанный кодогенератор, который бы сожрал 4 ГБ памяти, какую задачу он должен решать.

И вот если мы кладём на одну чашу весов кодогенератор, который работает микросекунду и жрёт 100KB памяти, а на другую - абуз шаблонов С++, который работает 10 секунд и жрёт 4GB памяти, при одинаковом конечном результате, то становится очевидно, что в метапрограммировании C++ что-то пошло не так.

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

проблемы, которые порождает эта «библиотечка», очевидно. если какое-то ненужно создаёт серьёзные проблемы - оно не нужно.

Iron_Bug ★★★★★
()
Ответ на: комментарий от hateyoufeel

У меня был вполне реальный рабочий проект на плюсах, где один файл не собирался на 32-битных системах, потому что 4G памяти не хватало. Спасибо Boost и такой-то матери. А сервисом пользовались десятки тысяч людей каждый день, так что реальнее просто некуда.

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

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

Это, конечно, хорошо, что на препроцессоре можно сделать любую дичь (*), за это мы его и любим.

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


(*) Отличный пример такой дичи – это имитация модульности на #include и стражах компиляции, к которой за полвека все привыкли настолько, что принимали её за настоящую модульность и искренне недоумевали, когда им говорили, что это не так. В C++20, наконец, подвезли настоящие модули, но в умы и библиотеки они заезжают гораздо дольше, чем в стандарт. Ну и эта тема, если я правильно понял, про чистую сишку, а не про плюсы, в сишке, как я понимаю, никаких модулей не предвидится.

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

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

Даже такая банальная вещь как связанный список или RB-дерево требуют макроса (queue.h). Простейшие min()/max() требуют макроса. Если посмотреть на любой серьезный проект на C, макросы будут везде.

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

min/mах как макросы использовать не нужно

В Linux считают иначе. У тебя есть какой-то более весомый проект, чтобы мы считали твое мнение более ценным?

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

вероятнее всего, ты так написал конфиги для сборки. или такой говнокод, что он не собирался. я юзала буст лет 20+, с самого его основания. и никогда он ничего не требовал.

Мы наслышаны о твоих успехах в написании хелловорлдов :3

В моём случае, это был обычный парсер/генератор на Boost::Spirit для не самого сложного формата. Но темплейты в GCC жрут ооочень много памяти при сборке. Такие дела. Зато код в результате быстрый был.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от tinykey

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

а тебе домашнее задание: написать список и максимум/минимум без макросов. подсказка: это тривиально.

Iron_Bug ★★★★★
()
Ответ на: комментарий от tinykey

я уже вижу, что вы «считаете». у вас пока банальной грамотности не хватает, чтобы советы раздавать. идите, доучивайтесь.

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

какие макросы в списках и максимуме/минимуме, окстись

Очевидно, проверяющие совместимость типов. Это позволяет находить ошибки в compile-time.

а тебе домашнее задание: написать список и максимум/минимум без макросов. подсказка: это тривиально.

Тривиально написать что-то, что не проверяет типы. В результате в одном списке оказываются разные структуры и получается memory corruption. Умные люди сделали типизацию.

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

да, и boost::spirit я в своё время использовала, и немало. и ничего там не «распухало» до невообразимых размеров. вообще с памятью не было никаких проблем. и тогда даже компов с 4 гигами памяти у меня не было. максимум с двумя. очевидно, ты написал какую-то лажу, если он у тебя не поместился в памяти. или, может, использовал шланг, который слишком туп и вообще жрёт память. вот ещё один возможный вариант источника проблемы. я когда-то обнаружила, что шланг жрёт ресурсы, и не стала его использовать. и до сих пор не использую и не рекомендую. но не думаю, что даже шланг бвы выжрал 4 гига. слишком дохрена.

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

какие макросы в списках и максимуме/минимуме, окстись!

Посмотрите исходники Линукса. Там почти все списки сделаны через макросы. Да ещё в придачу макрос foreach для обхода всех элементов списка сделали.

Линукс – говнокод?

X512 ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.