LINUX.ORG.RU

Что менее монструозное в 2020 как библиотека: Qt или GTK для C++ разработки чисто под linux?

 


3

4

Есть старый C++ GUI сделанный в 2012. Собирался под win и linux. Поддерживать win надоело, сам её не юзаю, да и мастдай уже произошёл. Qt была выбрана по совету знакомых как супермегапростая штука. Хотя юзал из всего набора минимум - окна, кнопки и иконки.

Глядя на сегодняшний мир всяких убунт, мы видим что GTK как-то более распространён (или так только кажется)? Никакого Qt в базовых интерфейсах, никаких KDE и прочего говнища.

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

Так чё, на GTK всё переписать, чтобы быть в тренде и меньше гимора в дальнейшем? К тому же, никогда не нравились всякие эти ненативные приблуды в Qt вроде MOC или как там его. Хочется что-то ламоповое без cmake, минималистичное, быстрое, современное и самое трендовое. Поддержики всякого JS-кода в интерфейсах, звука, воспроизведения видосов не требуется (есть вывод звука, но там на ALSA всё руками сделано по-пацански).



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

В 2020 году нет не единой причины использовать голый Си.

Если специалисты по этой предметной области предпочитают Си из-за синдрома утёнка или иных причин - приходится Си. Плюс за счёт простоты семантики Си даже средний кодер предскажет во что скомпилируется конкретный участок кода. В крестах есть океан нюансов. Например, я недавно узнал, что в коде:

std::vector<int64_t> f() {
    std::vector<int64_t> result;
    //lot of code
    return result;
}

за счёт copy ellision этот вектор будет создан не на стеке f, а на стеке вызывающей функции, причём это может происходить рекурсивно! Это описанная в стандарте оптимизация, объект вообще не копируется, move тоже не происходит. Таких нюансов - множество, сходу понять, какой ассемблерный выхлоп даст код - нетривиально. А в самом что ни на есть лоу левел - необходимо.

На практике любой проект на крестах (кроме разве что компиляторов) использует определённое подмножество крестов. Субсет крестов для лоу левел - может стать началом грандиозного срача.

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

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

Плюс за счёт простоты семантики Си даже средний кодер предскажет во что скомпилируется конкретный участок кода. В крестах есть океан нюансов.

Значит не надо пользоваться функционалом C++ который программист не понимает. Как минимум классы, владеющие указатели и RAII можно смело использовать.

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

Плюс за счёт простоты семантики Си даже средний кодер предскажет во что скомпилируется конкретный участок кода.

Для современных компиляторов Си это давно не так. Компилятор может много чего менять при оптимизации и может сломать код если в нём есть undefined behavior.

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

Значит не надо пользоваться функционалом C++ который программист не понимает.

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

Как минимум классы, владеющие указатели и RAII можно смело использовать.

Это нельзя называть крестами, нужно называть «Си с классами с фичами a, b и c». Львиная доля срачей начинается с «у царя кресты значат одно, у оппонента - совсем другое».

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

Это нельзя называть крестами

Если используется хоть одна фича C++ то это уже C++. Пользоваться всеми фичами C++ никто не заставляет.

Си с классами

Никаких «Си с классами» не существует. Есть либо Си либо C++.

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

Если используется хоть одна фича C++ то это уже C++.

Пользоваться всеми фичами C++ никто не заставляет.

Есть либо Си либо C++.

Ты же в курсе что всякие printf, scanf и примерно 99.9% фич С это и C++ тоже. Так что код который ты хейтишь скорее всего также собирается С++ компилятором, то есть это С++ по твоей классификации?

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

Никаких «Си с классами» не существует. Есть либо Си либо C++.

Ага, все С++ проекты одинаковые (сарказм). «Си с классами» - более-менее известное название подмножества С++. Если слон существует - автоматически существуют его составные части - хобот слона, лёгкие слона…

Если используется хоть одна фича C++ то это уже C++.

Без более точного контекста непонятно что может, а что не может выбранное подмножество С++. Между Си с классами и современными крестами с шаблонами на каждый чих и header only разница больше, чем между javascript и php. Даже на уровне синтаксиса.

Кстати, при сильном желании можно навелосипедить свою реализацию ООП в крестах с какой угодно магией в рантайме. Можно даже немного посыпать это синтаксическим сахаром. А можно расширить существующее ООП как угодно. Оправданность - другой вопрос.

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

Да ну. Меня тут лошадь не иначе как Linux фанатиком зовёт. Электрон нынче наступил. Скайп, Athom, VS Code, Discord, Signal, Wire, Slack, WhatsApp, а что там на Qt/GTK нового вышло/было переписано с электорна или другого GUI с момента выхода Electron-а? Сможешь назвать?

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

А почему в тегах только гтк?

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

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

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

Signal, Wire, Athom, VS Code не являются зондами. Ну и да, ты недооцениваешь то, что линуксоиды работают, а на работе зондами вполне принято пользоваться. Я вот пользуюсь Skype, Slack, и богомерзкой тележкой с зумом. Да, хочется блевать, но деньги важнее, так что живут они в firejail-е. VS Code и Discord-ом я тоже пользуюсь, первый удобнее vim-а для написания маркдауна, так как там всё нормально с превьюшкой и нет костыля с браузером, второй зонд для некоторых игровых сообществ, но на фоне других зондов я считаю его наименее противным (что не отменяет его жизни в песочнице). Вообще, если ты заметил, все средства коммуникации через интернет являются зондами и это неспроста.

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

ООП на С с макросами и указателями на функции лучше получается, чем дефолт в C++. можно нагородить какое-то подобие ObjC без ARC. C++ ущербен

Внесу свою лепту, поскольку с позицией и согласен, и не согласен. Я писал на gtk+ в свое время много месяцев, и этот опыт у меня отбил желание заниматься написанием гуев на Си.

Во-первых, Си не просто «лучше», а богатее фичами. ООП C++ — это отзвуки сишного ООП, в котором по умолчанию поле структуры — это как бы сразу подкласс, который можно передавать в функции со статической проверкой типа. Если при этом у вас явно обозначено выравнивание, то можно вообще кусками выгрызать группу полей из структуры. Одиночное наследование на этом фоне выглядит как ДЦП чел против Рональдо. В этом плане GObject и Vala — это поворот не туда.

Тезис номер два: подсчет ссылок — это смерть для многопотока. Вам просто нужно проверить значение поля у объекта, и с подсчетом ссылок вы вынуждены при этом увеличивать ссылку у родительского объекта, увеличивать ссылку значения, уменьшить счетчик значения, уменьшить счетчик объекта. Если к обьъекту обращается больше одного потока, то всё это будут кэш мисы, и ваша производительность простой проверки значения падает в разы, поскольку даже на самых оптимизированных под такую задачу процессорах доступ к ближайшему общему хранилищу в десять раз медленнее доступа к L1. Проблема не актуальна для однопоточного GUI, но мы же не собираемся фреймворк запирать в одном потоке, правильно?

Номер три: да, кресты ущербны. Они чудовищно перегружены бесполезным и опасным функционалом, примерно как это случилось с питоном. Это маркетинговый ход, который сделал кресты популярными, при этом одновременно сделав их говном. Как с питоном. Типовой программист на крестах, как и кодер на Си/асме, ходит по минному полю, но минное поле уже другое — теперь нужно аккуратно жонглировать шаблонами и объектами, избегая всех известных опасных фич языка, которых много, очень много, ни один кодер на крестах не знает все потенциально опасные и просто неприятные сочетания фич. То есть, геморрой поднялся выше по абстракциям, теперь проблема кривых указателей стала менее острой и появилась возможность увеличить средний размер проекта в разы при тех же затратах на его последующую поддержку, что и у меньшего по размерам сишного проекта.

Теперь по тезисам несогласия. Не получается «лучше», потому что отсутствие ограничений значит ответственность. В 95% случаев заказчику GUI приложения недопустимо, чтобы оно регулярно зависало, падало, или даже выполняло вредоносный код. Язык Си спроектирован будто специально так, чтобы толкать программиста на совершение сложно диагностируемых ошибок: неявные преобразования типов, переполнения буферов и значений, отсутствие нормальных массивов и передачи переменных по ссылке, вместо которых используются одни и те же топорные операции со ссылкой с минимальной проверкой при компиляции и выполнении. Особо терминальной стадией рака являются классические строки Си. Хуже того, ретрограды всеми руками и ногами упираются от того, чтобы сделать язык лучше. Те же безопасные функции работы со строками, которые Microsoft на правах монополиста ввел в своих продуктах и компиляторе, и которые, между прочем, есть в стандарте Си, не поддержаны другими компиляторами. При этом вводятся фичи вроде strict aliasing и оптимизаций non-volatile переменных, которые делают язык еще более непредсказуемым и неотлаживаемым. К слову, тот же Microsoft от этих фич отказался, добавив модификатору volatile вместо этого семантику атомарного доступа.

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

Именно эти причины и представляют собой похороны для Си в GUI, именно поэтому KDE и смежные приложухи, как правило, впереди гномовых по фичами — потому что «в Вилларибо уже веселятся, а в Вилабаджо ещё моют посуду». Попытка исправить положение была в виде Vala, но это лишь полумера, поскольку фичи GObject хоть и инкапсулированы/защищены, но логика приложения остается голой, в том числе поскольку классическое классовое ООП, реализованное в GObject, не подходит для абсолютного большинства задач — по-хорошему, оно плохо подходит даже для GUI.

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

Классы C++ лучше таблицы указателей на функции тем что компилятор проверяет совместимость типов и нельзя просто так перезаписать указатель на функцию. Это делает код безопаснее. Не говоря о том что таблицы указателей на функции выгладят ужасно. Исходники программ использующие GTK трудночитаемы в отличии от Qt

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

static PyTypeObject ShmObject_Type = {
    .tp_dealloc = (destructor) ShmObject_dealloc,
    .tp_repr = (reprfunc) ShmObject_repr,
    .tp_init = (initproc) ShmObject_init
}
В питоне тоже классы генерируются во время выполнения, но производится это по таким вот статичным таблицам.

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

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

В Си невозможно реализовать эффективное ООП без небезопасного каста указателей, которое может привести к порче памяти

Если вырубить strict aliasing и поставить за правило явно объявлять выравнивание структурам, то описываемая тобой проблема становится незначительной. Дикие указатели являются намного более серьезной проблемой, и кресты ее не решают. Автоподсчет ссылок заменяет одну проблему другой, как я уже написал в
Что менее монструозное в 2020 как библиотека: Qt или GTK для C++ разработки чисто под linux? (комментарий)

Тем более, что ты же не будешь на каждый int вешать счетчик, правильно?

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

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

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

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

В C++ можно писать код без единого static_cast/reinterpret_cast и из Си аналогов. Тип унаследованного класса совместим с базовым а this меняет тип при наследовании

Можно на руках ходить, но это не значит, что так делать удобно и эффективно. Обычно это приводит к созданию божественного базового класса, от которого должно наследоваться всё и вся для поддержки передачи в функции. Шаблоны в этом плане намного более приятны, поскольку могут прожевать самые разные типы данных. И таки обобщенное программирование в виде макросов в Си тоже есть, без необходимости небезопасного приведения типов.

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

Вообще, если ты заметил, все средства коммуникации через интернет являются зондами и это неспроста

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

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

Такой не зонд, что даже форк VSCodium создали

О, пасибки за инфу, а то я никак не мог понять, зачем MS вообще занимается этим проектом. Да, они продвигают свое облако, да, у них были в своем облаке наработки текстовых редакторов/wannabe-IDE, которые они позже оформили в VS Code с рекламой Azure, но все же мне казалось это недостаточным для оправдания проекта. Ниша пустует, бесспорно, поскольку Atom обладает низким качеством исполнения, но в мире колбасных огразков не так уж много желающих застолбить себе место. А теперь ясно — они же собирают телеметрию, а это нынче одно из любимых занятий мелкомягких. И в Visual Studio засунули телеметрию, и вообще чуть ли не во весь софт.

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

VS CODE OSS, а VSCodium ни что иное, как скрипты для автосборки VS CODE OSS. Ну и да, маковод палится

Visual Studio является зарегистрированной торговой маркой Microsoft, потому ты не имеешь права называть свой продукт этим именем. По этой причине любые сборки с официальной репы VSCode не могут содержать в своем названиие «Visual Studio». По этой причине формально можно заявить, что «Visual Studio Code» не является OSS, а в репе https://github.com/microsoft/vscode/ просто размещена некоторая часть исходных кодов «Visual Studio Code».

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

Скайп, Athom, VS Code, Discord, Signal, Wire, Slack, WhatsApp, а что там на Qt/GTK нового вышло/было переписано с электорна или другого GUI с момента выхода Electron-а? Сможешь назвать?

Я бы хотел подойти к вопросу с совсем другой стороны. А именно: что вообще нового выпускается для десктопа? И второй вопрос: сколько действительно качественных продуктов на электроне было написано? Я могу вспомнить только VSCode, всё остальное — это просто кал с плохой отзывчивостью и огромным даже по нынешним меркам потреблением ресурсов. В итоге Facebook отказался от выполнения в браузере и разрабатывает React Native.

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

VS Codium тоже можно натянуть на это, было бы желание

VSCodium чист, даже VSCode можно с натяжкой использовать для названия сборок Visual Studio Code, но это не «Visual Studio Code».

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

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

Чтобы такое сказать, нужно ни на чем кроме крестов и Си не писать. Потому что шаблоны в Си монструозны. Даже макросы Си компактнее будут. Проблема у макросового метапрограммирования совсем в другом — как эту штуку дописывать/переписывать, учитывая бессмысленные сообщения об ошибках от компилятора?

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

у крестового метапрограммирования есть фатальный недостаток.. 1 файл компилируется несколько минут, и никто не может понять что в нем написано (true story)

Да, есть такое.

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

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

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

Ты слишком широкими мазками берешь — шаблоны шаблонам рознь. Есть достаточно скромный STL, а есть Boost, или те же ренжи. Во многих проектах явно запрещено использовать буст и вообще тащить любые крупные либы с шаблонами в проект.

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

Правка: ядро Windows в основном на Си, но испльзовать C++ можно с ограничениями

Хорошая правка, потому что, действительно, основной язык винды — это Си. Правда, нужно также упомянуть, что компилятор Си от MS имеет поддержку структурированных исключений, так что для throw/catch там не нужны кресты.

В Си нет RAII и владеющих указателей, что приводит к битым указателям (use after free) и утечкам памяти. С++ может генерировать тот же машинный код при меньшем объёме исходного кода

Если ты про shared_ptr, то он будет таким же разве что при строго локальном использовании в функции. Если же он утекает наружу, то пойдет подсчет ссылок, куча записей в память — это ни разу не то же самое, что обычно делают в Си с указателями. Надеюсь, теперь ты увидел причину в 2020 году системный софт писать на Си.

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

На практике любой проект на крестах (кроме разве что компиляторов) использует определённое подмножество крестов. Субсет крестов для лоу левел - может стать началом грандиозного срача

Опытные программисты системщины и геймдева на крестах неизбежно приходят к Си с легкими нотками крестов. Проблема в том, что ньюфаги неизбежно просят правил и четких алгоритмов для написания кода, и совет «пиши наиболее простую программу, которая выполняет твою задачу» не прокатывает — это отсутствие правил, а неврозный ум требует наличия правил, наличия каких-то условностей, ему нужны готовые паттерны программирования, из которых он будет сидеть выбирать «подходящий», ему нужна иерархия классов «в качестве опоры», ему нужно еще куча других поводов для того, чтобы не писать код, а заниматься архитектурой. Той архитектурой, которая многократно раздует код и усложнит его поддержку.
Вот крайний пример, когда 700 строк «архитектуры» превратились в 5 строк чистого кода:
https://habr.com/ru/post/140581/ — Перестаньте писать классы

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

Ну кресты как бы содержат в себе сишку, так что иметь «чуть больше, чем Си» всегда приятно. Конечно, лично я бы предпочел паскаль, но вот беда — многие готовые решения и просто существующие проект писаны на C/C++.

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

Значит не надо пользоваться функционалом C++ который программист не понимает. Как минимум классы, владеющие указатели и RAII можно смело использовать

А ты точно прочитал пример, который он написал? Как раз из-за классов и RAII возникает много проблем.

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

Тем более, что ты же не будешь на каждый int вешать счетчик, правильно?

Из владеющих указателей есть не только shared_ptr, но и unique_ptr в котором нет счётчика и который не создаёт накладных расходов.

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

Для современных компиляторов Си это давно не так. Компилятор может много чего менять при оптимизации и может сломать код если в нём есть undefined behavior

Просто повторюсь на всякий случай:

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

У Microsoft был лучший компилятор Си в свое время. С тех пор GCC/Clang обзавелись RAII, а MSVC — перестал развиваться. Что, однако, не запрещает компилировать с «gcc --no-strict-aliasing» и с использованием безопасных функций из Safe C.

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

Из владеющих указателей есть не только shared_ptr, но и unique_ptr в котором нет счётчика и который не создаёт накладных расходов

Да, не создает. Только как ты с ним собрался работать? Безопасно передать его можно только по указателю, и тогда, внезапно, у тебя возникает проблема времени жизни указателя на умный указатель. За что боролись — на то и напоролись.

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

Если ты про shared_ptr

Нет, я про unique_ptr.

Надеюсь, теперь ты увидел причину в 2020 году системный софт писать на Си.

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

// C++

Object *NewObject(const Param &par)
{
	std::unique_ptr<SubObject1> o1(new (std::nothrow) SubObject1());
	if (!o1 || !o1.InitParam(par)) return NULL;
	std::unique_ptr<SubObject2> o2(new (std::nothrow) SubObject2());
	if (!o2 || !o2.InitParam(par)) return NULL;
	std::unique_ptr<SubObject3> o3(new (std::nothrow) SubObject3());
	if (!o3 || !o3.InitParam(par)) return NULL;
	std::unique_ptr<Object> obj(new (std::nothrow) Object(o1.release(), o2.release(), o3.release()));
	if (!obj || !obj.InitParam(par)) return NULL;
	return obj.release();
}

// C

Object *NewObject(const Param *par)
{
	SubObject1 *o1 = NewSubObject1();
	if (!o1) return NULL;
	if (!SubObject1InitParam(o1, par)) {
		Delete(o1);
		return NULL;
	}
	
	SubObject2 *o2 = NewSubObject2();
	if (!o2) {
		Delete(o1);
		return NULL;
	}
	if (!SubObject2InitParam(o2, par)) {
		Delete(o2);
		Delete(o1);
		return NULL;
	}
	
	SubObject3 *o3 = NewSubObject3();
	if (!o3) {
		Delete(o2);
		Delete(o1);
		return NULL;
	}
	if (!SubObject3InitParam(o3, par)) {
		Delete(o3);
		Delete(o2);
		Delete(o1);
		return NULL;
	}
	
	Object *obj = NewObject(o1, o2, o3);
	if (!obj) {
		Delete(o3);
		Delete(o2);
		Delete(o1);
		return NULL;
	}
	if (!ObjectInitParam(obj, par)) {
		Delete(obj);
		return NULL;
	}
	return obj;
}
X512 ★★★★★
()
Ответ на: комментарий от byko3y

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

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

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

В 2020ом tree-контрол выглядит в вебе примерно вот так

<tree-control>
	<tree-item title="first"></tree-item>
	<tree-item title="second">
		<tree-control>
			<tree-item title="first subtree"></tree-item>
			<tree-item title="second subtree "></tree-item>
		</tree-control>
	</tree-item>
	<tree-item title="third"></tree-item>
</tree-control>

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

DOM - это всего-лишь структура. Дерево. Такая же структура, как очередь или стек. Она ничего не говорит об отображении. За отображениие отвечает CSSOM, как минимум.

По существу твои нападки на DOM не более чем смешны. Спорить с тем, что web-ui это самый мощный, гибкий и кросплатформенный layout-engine на сегодняшний день, может только либо тролль, либо miltorg

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

Спорить с тем, что web-ui это самый мощный, гибкий и кросплатформенный layout-engine на сегодняшний день

… а также самый тормозной и потребляющий больше всего памяти. Qt QML намного эффективнее и содержит меньше legacy и всякого неочевидного поведения.

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

Qt сам по себе тормозной и потребляющий, в добавок еще и падучий.

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

В варианте на С у тебя говно. Никто из сишников так не пишет. Пишут лайфтаймы и всё. Никаких стенок из Delete не нарастает, ничего нет.

Object* NewObject(const Param* par)
{
	POOL_CREATE_ON_STACK(lt, 10);

	Object SubObject1* o1 = pool_add(&lt, NewSubObject1(), Delete);
	if (!o1 || !SubObject1InitParam(o1, par)) goto cleanup;

	SubObject2* o2 = pool_add(&lt, NewSubObject2(), Delete);
	if (!o2 || !SubObject2InitParam(o2, par)) goto cleanup;

	SubObject3* o3 = pool_add(&lt, NewSubObject3(), Delete);
	if (!o3 || !SubObject3InitParam(o3, par)) goto cleanup;
	
	Object* obj = pool_add(&lt, NewObject(o1, o2, o3), Delete);
	if (!obj || !ObjectInitParam(obj, par)) goto cleanup;

	return obj;
cleanup:
	release_pool(&lt);
	return NULL;
}

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

В С всё точно также. Пример выше.

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

Ваш Си код не корректный. NewObject принимает аргументы во владение. Так что если сработает условие if (!obj || !ObjectInitParam(obj, par)) goto cleanup;, то будет double free. Вы наглядно продемонстрировали как портить память на Си. К тому же я ни разу не видел ваших POOL_CREATE_ON_STACK и судя по второму аргументу оно создаёт дополнительный риск buffer overrun.

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

Ок.

Object* NewObject(const Param* par)
{
	POOL_CREATE_ON_STACK(lt, 10);

	Object SubObject1* o1 = pool_add(&lt, NewSubObject1(), Delete);
	if (!o1 || !SubObject1InitParam(o1, par)) goto cleanup;

	SubObject2* o2 = pool_add(&lt, NewSubObject2(), Delete);
	if (!o2 || !SubObject2InitParam(o2, par)) goto cleanup;

	SubObject3* o3 = pool_add(&lt, NewSubObject3(), Delete);
	if (!o3 || !SubObject3InitParam(o3, par)) goto cleanup;

	pool_release(&lt, o1);
	pool_release(&lt, o2);
	pool_release(&lt, o3);
	Object* obj = pool_add(&lt, NewObject(o1, o2, o3), Delete);
	if (!obj || !ObjectInitParam(obj, par)) goto cleanup;

	return obj;
cleanup:
	release_pool(&lt);
	return NULL;
}

Никак не меняет удобности С и С++. В С++ я точно также мог написать o1.get() вместо o1.release()…

и судя по второму аргументу оно создаёт дополнительный риск buffer overrun.

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

if (size >= lt->capacity) {
    perror("pool_add: too much resources for stack pool");
    abort();
}
fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

В С++ я точно также мог написать o1.get() вместо o1.release()…

Ме могли. Если бы владение не передавалось, вместо указателей в new Object были бы ссылки. unique_ptr::get() нужен только в исключительных случаях.

то программа просто упадёт.

Работает критическая программа на сервере или embedded системе и вдруг падает…

Кстати можете показать пример проектов использующих «POOL_CREATE_ON_STACK»? Google даёт 0 результатов.

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

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

Во-первых, я не согласен с программой на Си. Ее можно написать как-то так:

Object *NewObject(const Param *par)
{
	SubObject1 *o1 = NewSubObject1();
	if (!o1 || !SubObject1InitParam(o1, par))
		goto error;

	SubObject2 *o2 = NewSubObject2();
	if (!o2 || !SubObject2InitParam(o2, par))
		goto error;

	SubObject3 *o3 = NewSubObject3();
	if (!o3 || !SubObject2InitParam(o3, par))
		goto error;

	Object *obj = NewObject(o1, o2, o3);
	if (!obj)
		goto error;
	else
	{
		o1 = NULL;
		o2 = NULL;
		o3 = NULL;
	}
	if (!ObjectInitParam(obj, par))
		goto error;
	
	return obj;

	error:
	if (o1) Delete(o1);
	if (o2) Delete(o2);
	if (o3) Delete(o3);
	if (obj) Delete(obj);
	return NULL;

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

Во-вторых, в GCC и Clang появился RAII, потому код выше теряет секцию «error» и вместо «goto error» появляется «return NULL».

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

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

Прохладная история. Как будем гарантировать, что объект-владелец еще жив? Ну то есть вопрос тот же: как мы будем контролировать время жизни передаваемых между функциями данных? Либо ручное управление, либо подсчет ссылок.

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

Кстати можете показать пример проектов использующих «POOL_CREATE_ON_STACK»? Google даёт 0 результатов.

Потому что это С. Каждый может использовать свои имена.

Ну например вот: https://github.com/tsoding/nothing/blob/master/src/system/lt.h

Имена другие но идея использовать пул ресурсов в С и хранить там лайфтаймы такая же как и у меня.

Наверняка где-то ещё можно найти.

fsb4000 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.