avva: (Default)
[personal profile] avva
(будет интересно программистам на C++ и вряд ли кому еще)

Автор заметки std::visit is everything wrong with modern C++ несколько преувеличивает масштабы проблемы, но проблема тем не менее существует и реальна. Он пишет про новый тип std::variant в C++17, который позволяет сохранять в одном значении один из нескольких разных типов. В старом добром C такое делали втыканием внутрь структуры одновременно union и переменной, означающей, какой из членов union реально присутствует. std::variant позволяет добиться примерно того же, но с статической проверкой корректности. При том, что проверить наличие конкретного варианта внутри std::variant легко и понятно с помощью std::get, хочется также иметь возможность сделать аналог switch, выполняющий разные действия для разных вложенных вариантов - так, чтобы компилятор проверял, что все варианты указаны. И вот это, пишет автор, комитет по разработке C++17 сделать убедительно не смог - либо надо писать громоздкий класс с переопределением оператора вызова (), либо вообще заниматься какой-то прикладной магией типа рекурсивных темплейтов.

С одной стороны, он прав. В том виде, в каком std::visit сейчас существует, им неудобно пользоваться, и это упущение со стороны комитета (которое, возможно, будет исправлено). Но он неправ, когда пишет, что эта ужасная сложность самого языка показывает, что C++ двигается в неправильном направлении... это поезд, который давно ушел. C++ был слишком сложным языком для простых смертных в 2014-м году. До этого он был слишком сложным языком для простых смертных в 2011-м году, а до этого он был слишком сложным языком для простых смертных в 1998-м году, и сказать по правде, он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно.

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

А именно, формула такая: простой интуитивный API, предсказуемое и прозрачное использование памяти и копирование объектов; а если для воплощения всего этого нужна продвинутая магия, пользователю не нужно о ней знать. Магия остается спрятанной в исходниках библиотеки.

Это было верно в отношении std::string, std::vector и std::pair еще в 90-х. Для того, чтобы их написать, включая удобные методы их использования, нужно было знать много трюков и хитрых углов стандарта. Для того, чтобы использовать, нужно было просто интуитивно представлять строку как объект, сам хранящий память и расширяющий ее по мере надобности, вектор как очевидный аналог массива объектов итд.

Это остается верным в отношении std::unique_ptr и std::optional сегодня. Если читать их исходники, то можно ошибиться и на секунду подумать, что забрел в какой-то проект на Скале. Зато использование вполне интуитивно.

std::variant немного выбивается из этого паттерна, особенно в том, что касается проблемы "посещения всех альтернатив", и близок скорее к философии Boost - откуда он и взят почти без изменений, собственно. То, что C++{11,14,17} в целом сопротивлялись Boost-ификации языка и выносу продвинутой магии на поверхность, там, где программистам нужно постоянно с ней сталкиваться - одна из причин успеха современного C++.

Не верите мне? Спросите Джона Кармака:


Date: 2017-09-16 05:32 pm (UTC)
From: (Anonymous)
Да. Надо сначала формулировать, а затем шпицрутенами поддерживать дисциплину программирования. А когда надо, чтоб Curiosity долетела и села, переходить на Си.

Date: 2017-09-16 05:55 pm (UTC)
From: [identity profile] spamsink.livejournal.com
и сказать по правде, он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно

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

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

Date: 2017-09-16 07:06 pm (UTC)
livelight: (hot)
From: [personal profile] livelight
Вы забыли посчитать язык препроцессора :)

Date: 2017-09-16 07:19 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Действительно, теперь надо и его считать, раз уже и он объединён общим парсером.

Date: 2017-09-16 05:58 pm (UTC)
From: (Anonymous)
Делов-то. Кто-нибудь напишет правильный overload, выложит на гитхаб, и все станут пользоваться.

Date: 2017-09-16 07:05 pm (UTC)
livelight: (lightning)
From: [personal profile] livelight
Имхо, насчёт слишкомсложности в 1998 году вы преувеличиваете - если "простым смертным" считать того, кто как-то освоил язык просто-Си. А если "простым смертным" считать пррлетария, не знающего, с какого бока подходить к просто-Си, и не способного его освоить без кровавых мозолей на мозге, то для него и просто-Си имени К & Р слишком сложен, по определению.

Date: 2017-09-16 07:21 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Насколько я помню, виртуальное множественное наследование некоторым освоившим просто Си казалось слишком сложным с самого начала.

Date: 2017-09-16 08:10 pm (UTC)
From: (Anonymous)
Оно слишком хрупкое. Его нельзя делегировать, например.

captcha: avenida heritage ;)

Date: 2017-09-17 06:18 am (UTC)
From: [identity profile] mtyukanov.livejournal.com
Оно было слишком ненужным, пока не нашлось применение в виде интерфейсов. Его использование до того практически всегда означало плохой дизайн. Из-за ненужности и сложность -- запоминать то, что применяешь раз в несколько лет... Лонгджампы сишные в сегментных моделях тоже были непросты, но ими пользовались постоянно.

Date: 2017-09-16 07:53 pm (UTC)
From: [identity profile] fima.livejournal.com
Я вот использую std::variant и никаких проблем с написанием визиторов не испытываю. Гораздо больше раздражает невозможность в дебаггере, по крайней мере, в lldb, посмотреть какой же вариант сейчас сидит в переменной. Но это проблема дебаггера, надеюсь, рано или поздно это нормализуется.

Date: 2017-09-16 08:08 pm (UTC)
From: (Anonymous)
gdb прекрасно показывает

Date: 2017-09-16 08:06 pm (UTC)
From: (Anonymous)
>он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно.

Он был слишком простой в 1990. Недостаточно поддержанным.

Date: 2017-09-17 08:34 am (UTC)
From: [identity profile] vfork.livejournal.com
QVariant решает эти вопросы почти идеально. А поскольку он не наследует от QObject, то этот подход может быть использован и вне Qt

Date: 2017-09-17 09:32 am (UTC)
migmit: (Default)
From: [personal profile] migmit (from livejournal.com)
С плюсами у меня примерно как с эрэфией: если и подумаешь иногда «а может, можно будет и вернуться как-нибудь?», то достаточно прочитать какую-нибудь новость из этого мира, и дурь проходит.

Брррр

Date: 2017-09-17 02:31 pm (UTC)
From: (Anonymous)
си++ избыточно сложен, отвратителен и нелеп ибо был зачат в суете, молодым глупым программером, только и думавшим как бы в него побольше фич завернуть. Синтаксис поганый. Множественное наследование уродливо и запутано. Модификаторы доступа конечно еще больше огня поддают, на пару с генериками. Референсы, френдшип и консты как-то сделаны по-дурацки - намерение благое, но исполнение дурное. Чтобы реализовать тривиальную для жавы делегацию, надо целый концерт с бубном устраивать.

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

Date: 2017-09-17 02:59 pm (UTC)
From: [identity profile] daria klukin (from livejournal.com)
Когда о проблемах с++ говорят на примерах подобно этому это похоже на критику русского алфавита неспособного правильно передать звук другого языка.

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

Date: 2017-09-18 05:48 am (UTC)
From: [identity profile] gul-kiev.livejournal.com
Мне кажется, что программисту полезно понимать, что и как происходит "под капотом". Это позволит обходить грабли и выбирать более эффективные решения. "Оно работает на какой-то магии" - это подход гуманитария, а программисты - инженеры.

Конечно, если у РК86 можно было полностью дизассемблировать и прочитать monitor, у msdos знать таблицу функций 21-го прерывания, то потом всё знать уже стало невозможно, приходится полагаться на то, что всякие библиотеки и фреймворки работают в соответствии с документацией. Тем не менее, мне кажется, что хороший программист при написании кода хотя бы в общих чертах представляет себе, что получится в результате компиляции. Правильно ли ориентироваться на то, что программист этого всё равно не представляет, и скрывать всю магию внутри библиотек - не знаю, не уверен.

Нереально же

Date: 2017-09-18 06:07 am (UTC)
From: (Anonymous)
В проектах сложнее чем хелловорлд хотя бы на 3 порядка приходится использовать такое количество библиотек, что отдельному программеру просто невозможно знать детали реализации каждой. Приходится именно полагаться на порядочность и компетентность незнакомых разработчиков либо изобретать велосипеды. Конечно базу нужно понимать - например, что каждый новый тред приносит с собой ненулевой размер стека, что переключение контекстов не происходит бесплатно и тому подобное. Но все тонкости? Увольте.

Date: 2017-09-19 12:58 pm (UTC)
livelight: (lightning)
From: [personal profile] livelight
> всякие библиотеки и фреймворки работают в соответствии с документацией

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

Date: 2017-09-18 03:14 pm (UTC)
From: [identity profile] luarvique.livejournal.com
"C++ to C is what lung cancer is to lungs."

Date: 2017-09-23 07:50 am (UTC)
From: [identity profile] loyso-b.livejournal.com
Эх - типичные проблемы general purpose languages. Как всем быть счастливыми с единственным компромиссным API на всех.

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
2829 30 31   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 2nd, 2026 06:15 am
Powered by Dreamwidth Studios