Как стать автором
Обновить

Комментарии 92

> Комитет уже попробовал такой подход в С++11, когда поменял разметку std::string.
> Ничего хорошего из этого не вышло.

а можно подробности?
инфы действительно немного, но как минимум по этому поводу есть небольшая статья у gcc: gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
основной идеей было начиная с C++11 запретить реализовывать std::string как copy-on-write строку, а также стандартизировать SSO(small string optimization), что конечно же ломало ABI строки.
все равно не пойму — есть проблемы с точки зрения разработчика, использующего std библиотеку при смене ABI?
если вы используете STL (то есть по сути подключаете только заголовки), то никаких проблем нет, так как программа каждый раз по сути собирается из исходников, компилятор просто инстанцирует шаблоны. Проблемы начинаются тогда, когда ваше приложение собирается в виде liи/dll/so файла и наружу торчит что-либо из стандартной библиотеки.
НЛО прилетело и опубликовало эту надпись здесь
Там были проблемы в link-time, но проблем в runtime я чтото не упомню
хотите хоронить с++ — тяните билетик, запасайтесь провиантом и вставайте в очередь.

Часть изменений, которые назвал автор статьи, влекут поломку не только ABI, но и API (смешались в кучу люди, кони). Поломка первого почти болезненна, переход занимает всего лишь лет 5. Поломка второго неизбежно фрагментирует плюсы так же, как когда-то питон, когда язык по сути разделился на два параллельно существующих по сей день.

Если не подготовить способы внедрять изменения безболезненно, сообщество столкнется с тривиальнейшей проблемой: потом придется менять еще раз. И не единожды. А переписывать код до бесконечности любят не только лишь не все.
И тем не менее, Python 3 продолжает развиваться и преобладает по сравнению со 2-ым (поддержка которого к слову уже закончилась вместе с началом 2020 года). По сути сейчас все оставляют как есть в угоду компания со своими древнейшими жирными монолитами кода, а из-за этого страдают новые проекты. Хотя по-хорошему в таком случае нужно просто оставаться на старой версии языка/компилятора.
И тем не менее, Python 3 продолжает развиваться и преобладает по сравнению со 2-ым
он не так давно начал преобладать
поддержка которого к слову уже закончилась вместе с началом 2020 года
да да, а для работающих на втором питоне сервисов поменялся разве что таймстамп
По сути сейчас все оставляют как есть в угоду компания со своими древнейшими жирными монолитами кода, а из-за этого страдают новые проекты
не так просто. Есть у вас какой-нибудь проект на линуксах, который использует 100500 библиотек. Вот чтобы перевести его на новый стандарт с поломкой ABI нужно не только пересобрать ваш проект, но и чтобы все мейнтейнеры пересобрали и выложили эти 100500 библиотек. И если хоть одна из этих либ будет проприетарной, вам придется ждать пока эта контора обновит библиотеку. Если вообще когда-либо обновит.
Если есть проект который использует 100500 библиотек, и не может быть серьезно изменен (отказаться от несовместимых библиотек), то что мешает оставаться на старых плюсах? И по сей день можно непринужденно использовать С++11, чем, собственно, многие крупные компании и занимаются.
И заодно заставить вендоров всех этих 100500 библиотек тоже не использовать при их сборке ничего выше C++11?
НЛО прилетело и опубликовало эту надпись здесь
Даже если в них есть критичные баги или уязвимости?
НЛО прилетело и опубликовало эту надпись здесь
В закрытых библиотеках что-то бэкпортить самому довольно проблематично.
НЛО прилетело и опубликовало эту надпись здесь
Так пусть вендор бэкпортит.
М-м-м.
НЛО прилетело и опубликовало эту надпись здесь
Это была попытка выразить небольшое сомнение :)
НЛО прилетело и опубликовало эту надпись здесь
Не, либо вендоры используют новую ABI, и проблем нет, либо вендоры не хотят обновлять либу, и тогда все вместе старый ABI.
Ну вот смотрите. Предположим, в очередном новом стандарте было изменено внутреннее представление/разметка какого-то контейнера. И вот основной код и большая часть библиотек у вас используют старый ABI, но некоторая часть использует новый, причем эта часть, нопремер, распространяется вендором без исходников, binary only. И вот из кода, собранного в старом стандарте, нужно передать такой контейнер в код, собранный в новом стандарте (ну, или наоборот), чтобы он там с ним поработал как-то. Что делать будете? А если таких вендоров много, и часть распространяет свои собранные либы со старым ABI, а часть — с новым?

P.S. Вот здесь собственно проблема и все варианты ее решения (которые «оба хуже») уже обозначены.
Краткое содержание статьи: «Stable ABI Nonsense». :)

Сначала добавление префикса "co_" без какой бы то ни было веской причины, теперь отказ от такой очевидной вещи, как возможность смены ABI в мажорном релизе и снова без веских на то причин… Всё это как минимум не выглядит разумным.


Решением части проблем с ABI было бы возможность обращаться к данным класса через указатель, тогда бы и разметкой класса был всего лишь этот указатель. Идея очень близка к идиоме PIMPL, которая активно используется в Qt из-за его ABI.

К слову, Qt ломает ABI каждый мажорный релиз. Никто от этого не умер.

Qt и в пределах мажорного релиза (5.3_WinXpCompatible-to-5.4_Win7+) ломали, вроде умерли не только лишь все. Был лишний повод обязать клиентов обновить Windows, и то где-то в районе версии 5.13, да и то из-за определенных проблем MinGW до 7й версии. Технически кому надо — соберет и под 5.3.

А так, от stdlib для бОльшего количества разработчиков не хватает на самом деле самых простых вещей — networking, простой в использовании async, тот же regex удобный, для библиотекарей — наверное комфортные концепты для templates, может даже математики векторной/матричной завернуть тоже, комфортный multithreading/multiprocessing… и что-бы все было гарантировано кросс-платформенное и из коробки.

Тонкие материи пусть обсуждают и принимают хоть до 3-го пришествия, но то что есть сейчас в приличных языках, почти из коробки, должно быть уже сегодня в C++.
НЛО прилетело и опубликовало эту надпись здесь
Немного нечестно с моей стороны писать тут, потому что cor3ntin не знает русского, но:
* «Сделать ассоциативные контейнеры (намного) быстрее» — нет, не «намного»! Предложенные изменения для стандартных контейнеров ломают в первую очередь API, потому что они убирают методы для работы с нодами и итерации по корзинкам.
* «Ускорить работу std::regex (На данный момент быстрее запустить PHP и выполнить на нем поиск по регулярному выражению, чем использовать стандартный std::regex)» — основное что тормозит в std::regex, это локали. Убрать локали — это изменение API а не ABI.
* «Некоторые изменения в std::string, std::vector, а также в разметке других контейнеров» — скорее всего речь идёт про добавление SSO в vector, а это прежде всего ломает его гарантии по инвалидации итераторов. То есть это опять слом API а не ABI.
* «Единство интерфейса классов: на данный момент некоторые их реализации намеренно не соответствуют единому интерфейсу в угоду стабильности ABI» — да, это осознанное решение одного единственного вендора. И что бы не решил в этом месте комитет — это личное дело вендора, когда именно ломать ABI. Планы комитета стандартизации, которые пойдут в разрез с планами вендора, будут проигнорированы. Ибо от ABI зависит бизнес вендора и его финансовое благосостояние.
* «Предложение добавить фильтр в recursive_directory_iterator было отклонено, потому что сломало бы ABI» — оно было отклонено, потому что оно дурное. Автор предложения неправильно написал бенчмарк, что сводило полезность и достоверность его предложения на 0.
* «Предложение сделать большинство функций из библиотеки constexpr (включая strlen) скорее всего тоже будет отклонено, ведь ломает ABI» — это можно реализовать без слома ABI. Комитет отправил нас исследовать этот вопрос, мы поисследовали, всё ОК.

Ну и в целом: голосование решило что форсить слом ABI не будем, потому что вендоры могут не поддержать; голосование сказало что при наличии достойной идеи ломать ABI — это ОК. Трагедии особой не вижу. Единственная проблема — голосование получилось нейтральным, из-за этого противники и сторонники слома одинаково недовольны.
да, это осознанное решение одного единственного вендора.

А можете намекнуть, что это за вендор?
GCC. Все коммерческие продукты, поставляемые в бинарном виде для Linux, надеются на неизменность ABI, благодаря чему они могут не пересобирать свой продукт под каждый новый дистрибутив.

Разумеется можно сломать ABI, но тогда коммерческие продукты вынуждены будут либо
* собирать только под новый ABI, и забросить поддержку старых платформ
* собирать только под старый ABI (потому что он везде поддерживается), и тогда новый ABI немного теряет смысл.
* собирать под новый и старый ABI, что они навряд ли захотят делать
а можно как-то в одной libstdc++ смешать символы с двумя разными ABI, например?

Да, они так уже делали, но только это решает лишь проблему работы старых либ, зависимых лишь от libstdc++, на новых системах. Все остальное так же остается проблемой.

ну это дает полную обратную совместимость. А новый код можно порекомендовать собирать со static-libstdc++

Не совсем. Библиотека использует старые std::string, а приложение — новые. Ладно, мы разработчики приложения и можем сказать использовать старые std::string тоже, но тут появляется вторая библиотека, на которую мы повлиять не можем, а она использует новые std::string.

А можете пояснить вот такой момент: для той же visual studio статическую библиотеку приходится собирать под 4 версии стандартной библиотеки ((дебаг + релиз) * (однопоточная + многопоточная)). И для каждой версии компилятора (2013, 2015 и т.д.) свой набор ещё конечно же.
Я верно понимаю что GCC сохраняет совместимость на том уровне, что собранное статическое чудо условно версией 4.0 будет работать без проблем с версией 5.0, с другой соответственно реализацией стандартной библиотеки, другими "фишками" компилятора и т.п.?
Или какие-то ограничения есть?

И для каждой версии компилятора (2013, 2015 и т.д.) свой набор ещё конечно же.

Студия с 15 версии сохраняет своё ABI, библиотеки скомпилированные в 2015 версии без проблем линкуются в 2017 и 2019
так уж и без проблем. Вот например в 15.7 были проблемы. А в какой-то (то ли 15.4 то ли 15.6) я ловил вот такую бинарную несовместимость с атомиками.
Ну это по большей части баги, а так в основном проблем практически нет.
считайте что причина менять ABI c++ — поправить баги в проектировании языка и/или стдлибы.

Всё-таки неясно, в чем отличие от обычной ситуации с библиотеками: например, в debian часто в рамках одного дистрибутива бывает несколько версий одной библиотеки. Понятно, что если слинковаться с несколькими одновременно и передавать объекты, то будут проблемы.
Почему здесь, если поступить также и сделать две stdc++, то ожидаются непреодолимые трудности?

На самом деле, здесь есть другая проблема — если коммерческий продукт активно развивается и хочет идти в ногу со временем, то так или иначе он будет использовать новые возможности языка и библиотеки. И в этом случае он не будет работать на старых дистрибутивах со старыми версиями стандартной библиотеки даже при неизменном ABI. А обновлять дистрибутив на стабильно работающем боевом сервере никто не желает. Поэтому остается единственно приемлемый вариант «все свое ношу с собой». Конечно при неизменном ABI можно не таскать остальные библиотеки, но это только в том случае, если они остаются старых версий. А тут уже оказывается, что далеко не все мэйнтэйнеры так же пекутся о совместимости ABI в новых версиях библиотек. Да еще, если оставаться на старых библиотеках, порой патчи безопасности на них нужно накладывать, т.е. опять же делать свою сборку и тащить с собой. В общем — «куда ни кинь — всюду клин». Так что неизменность ABI не сильно спасает коммерческих вендоров.
А что мешает линковаться статически со стандартной библиотекой?
То что другие библиотеки могут линковаться динамически
Обычно их можно пересобрать.
А что делать с теми которые нельзя пересобрать? У меня таких вот очень много.

Добавлю к списку:


  • "Создание неявных виртуальных деструкторов для полиморфных типов"
    Плохая идея сама по себе, даже если бы не требовала слома ABI.
  • "возвращаемый тип у push_back может быть изменен, если сломать текущий ABI"
    Можно поменять и не ломая ABI, как это сделали в C++20 для std::list::remove.
  • "А вообще, действительно ли нам нужен и push_back, и emplace_back?"
    Объединить их можно было бы, но тут надо опять говорить об API а не ABI.
НЛО прилетело и опубликовало эту надпись здесь
я так понял, что это был перевод жалобной песни «комитет поломал улучшил стандартную библиотеку не так радикально, как я бы желал ее поломать улучшить».

PS: у нас на проекте своя реализация стандартной библиотеки (и не только ее. не спрашивайте), так что я на это все смотрю с попкорном. Лично я бы начал с того, что добавил способ спросить функцию в либе (хоть статической хоть динамической) — с какой ABI она умеет работать. А потом уже там все улучшал.
Как по мне надуманная проблема, можно переписать заново STL и выложить его как STL V2, что бы новые проекты уже писались на нем.
А что там с эпохами (те, что из раста)? Они вроде могут решить какие-то проблемы.

А, ну и C++, который мы потеряли. Все как обычно.

А кто первый предложил перейти на "std42::", т.е. тупо использовать разные неймспейсы для новых ABI?

НЛО прилетело и опубликовало эту надпись здесь

Пардон, но как могут быть те же проблемы с новыми именами. Кто мешает ломать совместимость каждые 10 лет в новом std:: ?

Проблема в сложности и проблема в обучении остаются точно такие же. Ждите статей и вопросов на собеседовании из разряда: «когда лучше использовать std31::unordered_map, а когда std42::unordered_map»?

Не могу согласиться.
Это не проблемы, а неизбежное следствие развития.


Как мне кажется, при наличии std11::, std14::, std17:: и std20:: обсуждаемой проблемы ABI просто не было-бы. Но возможно я тупо не в курсе какой-то общеизвестной причины? antoshkka?

Зато была бы другая — необходимость постоянно добавлять всякие перегрузки для новых stdXX, даже если у тебя все собирается из исходников одним и тем же компилятором, конвертировать эти stdXX туда-сюда (использую в своём коде std20, хочу использовать такую-то библиотеку, а у неё все с std11, все оборачиваем в какие-нибудь std20tostd11, даже если я её из исходников собираю). ИМХО тоже по-своему куча геморроя.

И?


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


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

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

хочешь новую клёвую структуру данных — обзови её по-другому
конвертировать эти stdXX туда-сюда
Ну, с другой стороны, если в каком-нибудь std::string ничего не поменялось, то он так и будет везде std::string, а не std11::string, std14::string, std17::string, std20::string, между которыми нужно будет постоянно конвертировать туда-сюда, хотя бы даже «для вида». Все-таки проще как-то.
НЛО прилетело и опубликовало эту надпись здесь
Я про вариант «хочешь новую клёвую структуру данных — обзови её по-другому». Я так понял, что возражение Antervis'а состояло в том, что в этом случае тоже придется что-то конвертировать в эту «новую клевую структуру», то есть если функция принимает std::super_duper_fast_map, то чтобы передать в нее обычный std::map, придется сделать конверсию. Мое возражение на это возражение состоит в том, что это нужно будет делать лишь иногда, в то время как в случае разных неймспейсов типа stdXX этим нужно будет заниматься постоянно, в коде будет куча мусора на эту тему.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Добавьте пожалуйста пример, как например, улучшается unordered_map и не ломая ABI приложение не собирается / не работает.

Все никак не могу понять: если сломать ABI, то какой смысл оставаться на С++?


Буквально на днях (в рамках "олимпиады" посвященной переписыванию wc) в очередной раз стало понятно что компиляторы разных языков выдают примерно одинаково работающий бинарь.


P.S. Я не против плюсов и своей профессиональной деятельности использую 2 языка: С++17, Python27.

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

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

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

Ну вот, к примеру, сопрограммы "подвозили" в язык 8 лет. Те, кто ушёл в другие языки — давно уже успели эти другие языки освоить, а то и забыть.

А вам принципиально, чтобы эта штука была именно в языке? Мне, честно говоря, не особо, есть в бусте — и хорошо.

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

Я уже пару лет активно пишу на Питоне (хотя и нерегулярно, да и в основном всякую мелочь), но всё равно постоянно ныряю в документацию и в целом чувствую себя гораздо менее комфортно, чем в C++.

Те "сопрограммы", которые в бусте, слишком прожорливы в плане памяти и переключаются не так быстро.

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

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


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

Это уж каждый сам для себя решает. Один из главных плюсов C++ лично для меня заключается в наличии огромного количества хороших библиотек на все случаи жизни, которые можно использовать напрямую, без придумывания, как бы это обернуть в какие-нибудь костыли в рамках C ABI для FFI (P.S. я о библиотеках с открытыми исходниками, для применения которых стабильность C++ ABI сама по себе не принципиальна потому, что их всегда можно пересобрать «под себя»). Новые концепции — это, конечно, хорошо, но это не есть самоцель с моей точки зрения, особенно если учесть, что особых проблем с концепциями в C++ тоже нет, он вполне себе мультипарадигмальный, и продолжает развиваться. Но, повторюсь, каждый для себя решает сам. Спорить на эту тему мне лень :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
А вообще, действительно ли нам нужен и push_back, и emplace_back?

Хм… А если конструктор приватный, как элемент в коллекцию с помощью emplace_back засунуть ?

Для этого и существует версионность стандартов. Хочешь использовать новый стандарт — смирись с его нововведениями. Если по каким-то причинам (например из-за зависимостей) нет возможности перйти на новую версию стандарта, придётся использовать старый.
Я проголосовал за немедленную радикальную смену ABI. Мотивация: это так встряхнет C++, что он либо возродиться жар-птицей, либо уйдет на задворки. Как-то так...)))
Понятно.
Будущее за Rust
Мне в этом плане нравится комментарий к какой-то там статье очередного адепта раста: «Nice article, but have you considered writing it in Rust instead of html?» :)
То есть вы думаете rust'а эта проблема никогда не коснётся?

Неизбежно коснётся, но будет шанс дойти до более существенных граблей.

но будет шанс дойти до более существенных граблей.

А на чём основана ваша уверенность в этом?

Не коснётся, потому (стабильного) ABI нет ¯_(ツ)_/¯

Понятно. Будущее за Rust
Сорвали с языка )) Если идет переписывание ABI, то почему бы не создать новый С+++ без обратной совместимости и без ошибок прошлого.

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

Да, я в курсе. Но, чтобы использовать, к примеру, тот же Qt, нужно сначала написать для него сложную обертку, которая низводит всю мощь его C++ интерфейса к ограниченному функционалу «сишной библиотеки», вполне вероятно, наделать при этом ошибок (чем больше оберток, и чем они сложнее, тем больше потенциальных ошибок). В общем, drawbacks имеются, и они значительные.
На моей памяти «убийц C++» уже много понасоздавали...
Это не значит, что у любого следующего не получится.
Или может, мне не стоит использовать C++ в принципе?

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

Поэтому да, ломать ABI (и пожалуй API тоже, но с умом). С ABI, пожалуй, всё ясно — открытые исходники просто пересобираются. С закрытыми всё относительно плохо, но если выбирать, либо развитие, либо смерть, то выбор очевиден. Нет, конечно, полностью C++ не умрёт, как не умер FORTRAN, но стагнация и потеря популярности неизбежна. Важно только при изменении ABI сделать следующее такое изменение (а оно тоже неизбежно), менее болезненным.

Другое дело, как влияют на принятие решений комитетом те, кто заинтересован в заморозке ABI. Ведь понятно, что множество корпораций и фирм готовы принести C++ в жертву своим сегодняшним прибылям и выгодам. И их сегодняшние сиюминутные выгоды могут перевесить потери вызванные стагнацией языка. Но это лишь говорит о том, что если не поменять ABI сегодня, завтра это будет сделать ещё сложнее (== невозможно).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории