Testing Stage’19: Technical | Security | Management and Approach — Early bird till 21 Dec. Hurry up!
×Закрыть

C++ 17 в реальних проектах

Цікавить таке питання, чи використовується зараз на проектах C++17?

З мого досвіду ще не всі компанії/проекти перейшли на C++11/14 (мотивація мені їх зрозуміла і це не тема для обговорення).

Є уже реальні проекти з підтримкою 17 стандарту чи все ж таки очікувати такого ж вялого переходу як було з C++11 (років 3 мінімум)?

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Реальность «си++17 в реальных проектах» (к) (тм) такова что уже и в си++ «решением» задачи «найти число пробелов в строке» будет выступать:

function countSpaces(str) {
    return str.split(' ').length - 1;
}

Честно стырено с совершенно реальной картинки ))

https://www.levels.fyi/assets/levelsfyi_triplebyte_footer_2340×1428.png

ЗЫ: причём ведь технических придирок как бы б и нет ведь оно действительно работает я проверял ))

Пишемо на C++14. Якоїсь прямо такої великої необхідності переходити на С++17 не бачимо. Швидше за все будемо чекати на С++20 і там уже дивитися варто чи ні.

Ми перейшли близько року тому на всіх проектах, як на нових так і на тих котрим по 15 років, як на мене дуже зручно)))))) Переходили зі старого стандарту та 10-ї студії. Звісно не завжди є можливість перевести великий ентерпрайзний проект на новий стандарт, тому вялість переходу є абсолютно нормальним явищем. Наприклад на Java 6, або .Net 2.0 також підтримується чимало проектів, так що нічого особливого з C++ як по мені не відбувається))))

Вот интересное предложение от Херба Саттера (один из первых в мире по C++, если кто не слышал). Но содержание грустное:

> Yet in [SC++F 2018], over half of C++ developers report that exceptions are banned in part (32%) or all (20%) of their code, which means they are using a divergent language dialect with different idioms (e.g., two-phase construction) and either a nonconforming standard library dialect or none at all.

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

Если пойдёт, то C++23 будет снова совсем другим языком.

пофиг. все, кого хоть чуть чуть волнует оптимизация, не используют исключения

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

Не хотите использовать исключения? Тогда мы идем к вам.

и исключим!

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

Кстати, если вы используете ретурн коды вместо эксепшенов, 17-ый стандарт вам может быть интересен как минимум атрибутом [[nodiscard]].

далеко не так однозначна.

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

17-ый стандарт вам может быть интересен как минимум атрибутом [[nodiscard]].

спасибо, посмотрю

если у вас есть инфа, как раскрутить ексепшн без накладных расходов

Такой инфы у меня нет.
Зато есть инфа, что код, использующий эксепшены, «on happy path» (когда эксепшены не вылетают) может работать быстрее по сравнению с кодом, использующим ретурн коды и последующие if’ы. Ибо последнему приходится постоянно проверять возвращаемые значения.

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

Зато есть инфа, что код, использующий эксепшены, «on happy path» (когда эксепшены не вылетают) может работать быстрее по сравнению с кодом, использующим ретурн коды и последующие if’ы.

можно ссылку?

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

Но оверхед это не самое страшное. С эксепшенами в принципе не просто ведь работать. Вот эти вот гарантии безопасности которые надо держать в голове. Спросил на импровизированном митапе у коллег, кто умеет. Чуваки с 10+ опыта в технологической компании, руку не поднял никто.

Ещё одна проблемма по ссылке выше — больше чем в половине проектов они забанены. То есть недоступны вообще. То есть и люди в этих проектах работающие скорее всего их и не умеют и не научатся (см мои коллеги).

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

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

Так что, как по мне, тут вопрос скорее не в том, чтобы «держать в голове» все сложности. А в том, чтобы один раз перестроить свой майндсет таким образом, чтобы научиться думать о коде с точки зрения exception safety. И потом оно как-то на интуитивном уровне включается, без особого напряга.

Спросил на импровизированном митапе у коллег, кто умеет. Чуваки с 10+ опыта в технологической компании, руку не поднял никто.

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

Ещё давно начитался Майерса и Саттера, тогда же и разобрался с этой мутью.

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

Блин, я фигею с ваших сложностей. Exception — исключительная ситуация. В логике программы не должно быть исключений. Они только для исключительных ситуаций, а не для логики выполнения.

Вот и Виктор с исключениями похоже не умеет работать.

В логике программы не должно быть исключений

Так то оно так, да не так.

В логике программы не должно быть исключений
Так то оно так, да не так.

В логике — не должно быть. Исключение эта та ситуация, которая неподконтрольна программисту (в первую очередь, конечно, нехватка памяти), а об этом часто забывают.
По факту же их используют как безопасный goto для латания дырок в кривом дизайне.

По факту же их используют как безопасный goto для латания дырок в кривом дизайне.

Та я же не о том. Это уже совсем опа.
Но используя исключения ты в своем «свободном от исключений» коде логики должен учитывать их наличие и думать о гарантиях безопасности исключений. Что как бы логику не меняет, но на дизайне кода след оставляет. Вот как бы и получается, что вроде бы «Хепи пас» без исключений, а как бы исключения эти надо постоянно в голове держать когда ты и хепи пас пишешь.. Может оно и не так сложно и не так уж и плохо. Ну чего там РАИИ использовать везде и всегда от этого же хуже не будет(а для этого кстати тоже кое-какие тулзы иметь не помешало бы, правда), думать о том как ты сохраняешь изменяемое состояние.... Но по моему это не совсем «без исключений»

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

Понимаешь, как на меня, исключения, как и goto, set/longjump, reinterpret_cast, friend, множественное наследование, RTTI относятся к вещам, без которых задача иногда (быстро|удобно) не решается, но это не значит, что в их категориях нужно мыслить при написании кода.

Не понимаю. Ну нельзя пользоваться исключениями для ошибок и постоянно не иметь их ввиду. Ну природа же у них такая. От goto, reinterpret_cast, friend ( в лонгджам я не умею) они отличаются локальностью. То есть эти штуки видны в коде в месте их использования, а вот ексепшен спокойно себе может пролетать из чужого когда в чужой же код «мимо» твоего кода, который такую возможность должен учитывать. Как о них постоянно не думать то? Не понимать.

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

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

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

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

Я отдаленно мысль улавливаю, но я не совсем согласен. Ты предлагаешь не плодить своих ошибок но только обрабатывать системные ошибки?
Ну вот смотри:

Исключение это тот случай, когда ты начал писать в файл, а кто-то вытянул флешку

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

И что ты предлагаешь в результате? ипользовать одновременно и ексепшены и ретурн коды что ли?

Или память не выдержала инстанциации очередного мегатемплейта

Во первых темплейты не едят память. Во-вторых, да я согласен, здесь можно и просто умереть.... Просто умереть? Черт, я ведь перед тем как просто умереть должен задампить стек, и отправить дебаговую информацию....

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

В смысле не представить? У меня как бы обычное дело.

Но тут уже «по-волчьи выть»

ну как бы да.

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

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

Ничем оно для меня от FileNotFound не отличается.

По месту принимается решение — или создали файл или вышли и забыли. Локально или уровнем выше, не далее.

И что ты предлагаешь в результате? ипользовать одновременно и ексепшены и ретурн коды что ли?

А они по факту и так вместе используются. Или API операционки начали генерировать исключения?

Во первых темплейты не едят память

Зато построенные на их базе объекты очень даже.

Черт, я ведь перед тем как просто умереть должен задампить стек, и отправить дебаговую информацию....

Зачем это нужно в релизе?

А они по факту и так вместе используются. Или API операционки начали генерировать исключения?

Вокруг АПИ обычно какой-то ПАЛ наворачивают. А ПАЛ эти бывают разные.

Зачем это нужно в релизе?

Для троблшутинга проблем в релизе, нет?

Для троблшутинга проблем в релизе, нет?

И че сильно помогает инфа, что «access violation at 0xXXXX» ?

Ну если ты можешь символизировать это

0xXXXX

 то да, сильно. А если полный стектрейс задампить — так вообще песня.

Зато построенные на их базе объекты очень даже.

Прямой связи нет. Если темплейты писали умеючи, то построенный на базе темплейта объект не выжрет больше, чем «обычный» объект не-темплейтного класса.
А не умеючи можно и обычные объекты заставить жрать больше нужного.

Если темплейты писали умеючи,

А если нет? А если надо внести мелкую правку?
Я готов доверится библиотечному, максимум несложному очевидному, но не написаному местным дарованием 2-3-кратно вложенному.

А если нет? А если надо внести мелкую правку?

Вносите. Я разрешаю :)
Больше тут ответить нечего (в настолько общем ключе). Всё зависит от конкретного примера, куда и какую правку нужно вносить.

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

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

Мой фремворк поламать апликейшен в этом случае права не имеет же. Мне эту ситуацию надо обработать и самому остаться как минимум

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

И что ты предлагаешь в результате? ипользовать одновременно и ексепшены и ретурн коды что ли?

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

начал писать в файл, а кто-то вытянул флешку.

written < want_to_write

Согласен, куда уж мне до местных сеньоров.

Это ты так думаешь )) ты просто редко видишь «обычную логику программы которая даже без ексепшинов» там голубая устрица чисто отдыхает ))

Ну на галерах разного насмотришься. Я тебя понимаю и «мне тебя жаль» ;)

и да откроиццо тибе истинна мой юный падаван галеры никогда не веслуют свой собственной код в принципе от слова вообще всегда исключительно код Тех Самых Продуктовых Компаний без вариантов внемле истенне и вот тогда понимание достигнет тебя ))

Кто тебе сказал, что для меня это новость? Я это понимаю. И я рад, что мне удалось попасть в коллектив с настолько близкими мне предпочтениями касательно использования C++. Здесь даже джуны умеют работать с эксепшенами.
Это ведь не такая сложная тема. Просто тем опытным программистам это не было интересно, в работе не использовалось — вот они и не вникали.
А переучиваться многим лень. Да и зачем, если проектов без эксепшенов тоже хватает?
В общем, тут каждому своё.

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

И я рад, что мне удалось попасть в коллектив с настолько близкими мне предпочтениями касательно использования C++

Ну в принципе да, рабоать с единомышленниками это таки успех.

Здесь даже джуны умеют работать с эксепшенами.
Это ведь не такая сложная тема. П

А що складного, обвернув все try — catch — finally і педалиш до усрачки і маєш щастя :).

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

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

Вопрос нужно ли?

Что нужно ли? Работать с ексепшенами? ну все-таки код более высокоуровневый получается, уровень абстракции повышается, растет процент жиров в масле. Каждому самому конечно решать но мне вот нравиться например.
Или думать про гарантии работая с исключениями? а без этого уже никак нельзя. И да. Ексепшены они таки ексепшенал, но все равно неизбежно оставляют след на том как ты пишешь код. Не факт что самый плохой след но все же.

longjmp же (не шучу)

Это же самый дорогой вариант реализации. Зачем?

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

Дык, эксепшены в «плюсах» это зло, на многих уровнях.

На каких «уровнях», и в чём тут специфика плюсов по сравнению, например, с C#?

Любой «не украинский синьор» плюсовик об этом знает.

«Синьор» не рассуждает о таких вещах в категориях типа «зло».

«Синьор» не рассуждает о таких вещах в категориях типа «зло».

Синьор, пользующий «плюсы» — не пользует эксэпшeны.

Если синьор ползует «плюсы», и при этом пользует эксэпшены — значит, это не синьор. Т.к. либо 1) занимается какой-то мелкой программкой, в виде «наколенного творчества», либо 2) занимается виндо-зависимым крупным проектом, без особых требований к реал-тайму, который нет смысла писать на «плюсах», т.к. есть смысл писать на «шарпе» 3) либо пишет какую-нибудь хрень для линуксов за еду.
Есть иные варианты?

Синьор, пользующий «плюсы» — не пользует эксэпшeны.

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

Есть иные варианты?

Есть — перестать кидаться лайном и перейти к конструктиву.

Ну, может и не прям оскорбления, но определённо демонстрация своей некомпетентности.

Есть иные варианты?

Есть: он живёт в 2018 году.

over half of C++ developers report that exceptions are banned in part (32%) or all (20%) of their code,

Я б даже сказал бы, что это мнение не сеньоров, а СТО.

Кстати конкретно в нашем случае это мнение ЦТО работавшего лет 15 назад.

Меня и текущая реализация не напрягает и мой код от них не тромозит. Единственное, чего в текущей реализации мне не хватает, это удобного для них механизма получения раскрученого стека при ловле исключения.

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

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

ЗЫ: плюс к.м.к. стандартные средства всё равно были по крайней мере что-то там в лог можно кинуть чтобы раскрученный стек показать давно я не писал кода по глубокому анализу и логированию всего )) года 3 наверное ))

Если пойдёт, то C++23 будет снова совсем другим языком.

Уже частично есть, может будет и в 20.

А нафига? Там, где нужна портабилити — старый-добрый 98-й или даже C. Там, где нужна новизна, ui и фичи — C#.
А где ниша для всего, что после 98?

а где нужна новизна, юай и портабилити?

а где нужна новизна, юай и портабилити?

Скорее всего C, накрайняк C++/98 + нативный (для платформы клиента) ui.

портабилити софта. ui — отдельная история.

ui — часть софта
юз кейс: мы пишем софт с гуем на плюсах. как нам обеспечить портабилити?

как нам обеспечить портабилити?

Я ведь выше написал. Делать гуй «нативным». Если портироваться должно на андроиды — гуй, соответственно, должен быть местным жабовым.

Всё остальное на C или «плюсах» — но не моложе 98 и с кучей ограничений (типа, без тех же эксэпшэнов).

а если 5 платформ? 5 вариантов гуя? а меинтейнить как весь этот зоопарк?

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

написать гуй кроссплатформенным

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

Но если делать гуй контролами — кросс-платформенности не будет.

Но если делать гуй контролами — кросс-платформенности не будет.

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

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

я знаю решение. и оно работает

а если 5 платформ? 5 вариантов гуя?

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

гуй хорошо отделён от остального

такого практически не бывает

MVC MVVM MVA MVP даже в «классическом» MFC 98-го года уже был Document-View на минуточку 20 годочков тому тому назад ))

я тоже знаю много страшных слов

много страшных слов

youtu.be/_O-QqC9yM28

такого практически не бывает

Бывает. Но не всем дано.

Ещё как бывет, посмотрите на веб — там отдельно сервисы с функционалом, отельно сервер для фронтенда.

посмотрите на веб

не могу, желудок пошаливает

сервер для фронтенда

ухтышка. это что за чудо?

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

Браузер, больше некому рендерить в вебе.

ок, как насчет веб аппов, икоников там всяких и прочих реактов?

Так собственно это и было про веб аппы, в том плане в котором я привык их видеть.

Если вы о традиционной схеме, ярким представителем которой является ПХП, то там есть конечно же различие в том, что в зависимости от запроса код, что отсылается клиенту разный, и по сему разные эффективные сервера для статического контента типа nginx тут остаются за кадром.

Так собственно это и было про веб аппы, в том плане в котором я привык их видеть.

Slack? Skype? у них логика тоже на сервере?

Так, кажется у нас рассинхрон. Схема о которой я говорю: браузер посылает запрос на сервер для статических ассетов и отуда получает html ину и пачку js кода — она большая и сама по себе может являтся приложением, туда напихано достаточно много логики связанной с отображением и представлением/обработкой UI. Насколько я понимаю она в подавляющем большинстве случаев пишется на JS или том что в него компилируется, и не так уж и сложна (а если прикрутить туда FSM то вообще не сложна).

Однако, логика связанная с разной доставкой сообщений и обраткой разного рода задач, находится на сервере (обычно не на одном).

А вы о чём?

Так, кажется у нас рассинхрон.

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

Только не говори мне, что Qt полон лямбд и новомодных шаблонов.

Qt полон лямбд

ты не поверишь ))

wiki.qt.io/New_Signal_Slot_Syntax

с версии 5.9 поддержка старых стандартов ц++ упразднена
есть и лямбды и шаблоны естественно (куда без них?)
нет эксепшынов и ртти (вроде бы)

Используем, насколько это позволяют компиляторы, под которые наш код должен компилиться.

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

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

Основным тулсетом для нас на данный момент является MSVC 2015. В ней уже есть некоторые фичи C++17, которые мы время от времени используем. Например, std::size для получения размера произвольного контейнера, включая простые массивы.
В шаблонном коде мне пару раз неслабо помогли std::conjunction/std::disjunction, сделав написание своих трайп_трейтов куда более лаконичным.
Когда обновимся на 2017, с удовольствием заюзаю class template argument deduction (долой костыльные make...-функции, которые пока что приходится писать) и structured bindings.

Короче, переход в реальных проектах есть — но да, он медленный.

В частности, как можно писать код, переопределяющий виртуальные функции в производных классах, без использования слова override? Это ж полнейший мазохизм.

шито?

и что она в каком-то месте поможет сделать код проще или избавиться от какой-то платформозависимой магии

например?

Основным тулсетом для нас на данный момент является MSVC 2015.

зачем!? он уже больше 2-х лет не обновляется а вы рассказываете за то якобы «используете фичи си++17» в чём конкретно проблема просто взять и взять студию 2017? Ну мне правда интересно.

Например, std::size для получения размера произвольного контейнера, включая простые массивы.

ну да это надо умеючи писать чтобы смешивать произвольные контейнеры с простыми массивами вообще основная мораль си++17+ как раз в том что все тренды продвижения это «бездумное использования крайне невдувчивыми падаванами» ну вроде как джава ))

Короче, переход в реальных проектах есть — но да, он медленный.

так а в чём же ж всё же ж вопрос взять и поставить студию 2017? Они по-моему даже покупные уже продаются только по подписке т.е. всё равно что 2015 что 2017 деньги те же ж. К тому же ж студия 2017 поддерживает все стандарты путём переключения «поддерживаемого стандарта языка».

шито?

То, что писать код без «override» — мазохизм, по моему мнению.
Да, компиляторы умеют эмитить ворнинги в случае чего, но читабельности кода это не помогает.

например?

Тот же самый std::size, если говорить именно о фичах C++17, которые доступны в 2015 студии. Или std::conjunction/disjunction/negation в тайп_трейтах, вместо ручных велосипедов. С их помощью сократили объём кода в парочке наших библиотечных шаблонов. И новые тайп_трейты, когда возникала потребность, писали уже с ними.
Больше пока примеров из этой практики не приведу, т.к. в VS 2015 доступно слишком мало нововведений 17 стандарта.

А если говорить не только про C++17, то, к примеру, было прикольно заменить __declspec(align(16)) вместе с его братом __attribute__((aligned(16))) — каждый из которых условно компилировался под соответствующую платформу в том или ином месте кода (перед или после определения класса) — на стандартный и лаконичный alignas(16).
Или всякие BOOST_FOREACH на обычный range-based for loop из C++11.
Ну и вообще, заменять старые самописные велосипеды на средства, которые теперь появились в стандарте.

это надо умеючи писать чтобы смешивать произвольные контейнеры с простыми массивами

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

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

бездумное использования крайне невдувчивыми падаванами

Унификация — это не «бездумное использования крайне невдувчивыми падаванами». Это попытка хоть как-то загладить кривости C++, где с одними контейнерами нужно работать вот так, с другими — по-другому. Хотя реальных причин для этих отличий попросту нет.

Вот вам задачка.
Дан контейнер C. Дано значение val. Нужно удалить все элементы, равные val, из контейнера C. Как это сделать? О простых массивах не говорим, их размер не меняется.
Но, допустим, вектор. Для него нужна классическая erase-remove идиома.
Set/map? Для них она не применима (ключи не move-assignable), зато есть свой метод .erase().
А что касается list? Это ж такой же node-based контейнер... Наверняка тоже метод .erase(), да? Нет, стандартизаторы не придумали ничего умнее, чем в этом подвиде контейнеров назвать аналогичный метод .remove(). Логика.

А так, вызвал одну глобальную функцию std::erase() на своём контейнере и не паришься. Она уже под капотом сама разберётся, что ей вызывать дальше.
Увы, она станет доступной только в С++20. Но аналог можно написать уже сейчас, владея шаблонной магией на достаточном уровне.

так а в чём же ж всё же ж вопрос взять и поставить студию 2017?

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

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

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

да именно про это я и имел в виду спасибо.

А если говорить не только про C++17, то, к примеру, было прикольно заменить __declspec(align(16)) вместе с его братом __attribute__((aligned(16))) — каждый из которых условно компилировался под соответствующую платформу в том или ином месте кода (перед или после определения класса) — на стандартный и лаконичный alignas(16).

А у вас какие-то телесные назания для тех кто сделал кросс-платформенный макрос alignas(), когда стандарта ещё и в помине не было?

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

И как вы себе представляете «кросс-платформенный макрос» alignas(), поделитесь секретом? Хотя бы такой, чтоб собирался под MSVC и GCC, многого не прошу. И чтоб это был один макрос, а не два, каждый из которых условно компилится под ту или иную платформу.

/// \macro LLVM_ALIGNAS
/// \brief Used to specify a minimum alignment for a structure or variable. The
/// alignment must be a constant integer. Use LLVM_PTR_SIZE to compute
/// alignments in terms of the size of a pointer.
///
/// Note that __declspec(align) has special quirks, it's not legal to pass a
/// structure with __declspec(align) as a formal parameter.
#ifdef _MSC_VER
# define LLVM_ALIGNAS(x) __declspec(align(x))
#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0)
# define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
#else
# define LLVM_ALIGNAS(x) alignas(x)
#endif

Действительно, не так всё страшно, благодаря тому что __declspec(align(x)) тоже можно разместить после слова struct. Как и __attribute__((aligned(x))):
godbolt.org/z/vqG7-K
Но это я проверил на более новых версиях компиляторов, которые уже имеют поддержку C++11 (хоть я её и указал стандарт C++98).

Разве более старые компиляторы тоже адекватно воспринимают эти __declspec/__attribute__ в этом месте?
Ибо в официальных примерах майкрософта __declspec стоит ещё до слова struct, а в документации GCC __attribute__ идёт в конце, уже после закрывающей фигурной скобки.

На том проекте, где мы заменили макросы на alignas(), таких макроса было два: в начале и в конце определения структуры. То ли писавшие это в своё время не догадались попробовать поставить их в это специфическое место, то ли старые компиляторы такое не поддерживали.

Действительно, не так всё страшно, благодаря тому что __declspec(align(x)) тоже можно разместить после слова struct.

Позиция declspec и __attribute имеет большой смысл. Перед словом struct оно относится к инстансу, после struct, оно относится к типу.

__declspec перед словом struct также относится к типу:
docs.microsoft.com/...​rsions/83ythb65(v=vs.140
(ну, разве что если вы создаёте инстанс сразу после закрывающей ’}’, перед точкой с запятой... тогда, наверное, приклеится к инстансу)

так а в чём же ж всё же ж вопрос взять и поставить студию 2017?

Видимо лень мешает выкачать и установить больше 10 гиг.

> Используем, насколько это позволяют компиляторы, под которые наш код должен компилиться.

И почему это, читая эту строчку, я сразу подумал про MSVC?!

Потому что MSVC один из них :) И да, в плане доступности новых фич именно он нас ограничивает больше всего.

Видел я таких сказочников, понаписывают компайл тайм г*внища и через пол года в другую контору. Он художник ведь, так видит :D

А как это связано со стандартом языка? Компайл-тайм г*внище было таковым в языке всегда. И раньше оно было ещё более уродливым, чем сейчас.
Если человек неудачно заюзал какие-то фичи «просто потому что это прикольно» — это вопросы к нему, а также к вашим процессам в команде (почему ему дали такое пропихнуть? код ревью вообще не проводилось?) — но никак не к стандарту C++.

Если человек неудачно заюзал какие-то фичи «просто потому что это прикольно»

например си++2017? ))

Да хоть C++98. Неудачно применить можно любую фичу любого стандарта.

Если человек неудачно заюзал какие-то фичи «просто потому что это прикольно» — это вопросы к нему

вот с этим согласен, всегда надо ясно понимать, что если новое, то не обязательно надо втыкать его где попало — работал с челом, который писал для себя, а не для людей (куча метакода, шаблоны везде где надо и не надо — полный набор).
Сам я не любитель использовать тот же auto, применяю обычно при итераторах, при ’range based for’-циклах, да при structured binding. Редко где ещё. Я предпочитаю в большинстве влучаев видеть тип сразу, а не искать его с помощью IDE. Кстати, не последняя причина этой неприязни кроется именно в IDE, которые очень не любят auto, макросы и шаблоны. Открыв приличного уровня проект (тот же bitshares 2.0(graphene)) в netbeans, clion, QtCreator’е — во всех будут свои проблемы. Последенее время сижу на clion, но сугубо из-за инструментария, скорость парсинга проекта совсем не радует и многие типы данных не определяются совсем.
Но в продолжении списка, хотелось бы ещё отметить улучшения в работе с maps и sets.

— splicing. Переместить элемент контейнера из одного set’а в другой можно теперь так:
auto handle = setNames.extract(User("John"));
outSet.insert(std::move(handle));
То есть не надо сначала удалять в первом, а потом copy/move’ать во второй.

— добавлены try_emplace() и insert_or_assign().
Первая позволит выполнить вставку в map, только если в нём уже нет такого ключа (то есть не надо выполнять предварительную проверку типа ’if (m.find("great") == std::end(m))’.
Второй либо выполнит вставку, либо обновит значение по указанному ключу:
auto [iter, inserted] = mapNicks.insert_or_assign("John", User("John Doe"));
if (inserted) {
std::cout << iter->first << " entry was inserted\n";
}
else {
std::cout << iter->first << " entry was updated\n";
}

Усовершенствованный emplace_back.
Который теперь сразу возвращает ссылку на вставленный объект:
// C++11/14:
stringVector.emplace_back("Hello");
stringVector.back().append(" World");
// C++17:
stringVector.emplace_back("Hello").append(" World");

Ещё есть Parallel STL Algorithms. Объёмное новшество, позволяющее с помощью policy-типов std::executin::seq, std::execution::par и std::execution::par_unseq указывать с какой производительностью мы хотим использовать стандартные алгоритмы. Да, очень иногие из алгоритмов уже принимают доп. параметр ExecutionPolicy (например, тот же std::copy — en.cppreference.com/w/cpp/algorithm/copy)

netbeans, clion, QtCreator’

QtCreator 4.8 научился auto и теперь есть поддержка language servers

Сам я не любитель использовать тот же auto... Я предпочитаю в большинстве влучаев видеть тип сразу, а не искать его с помощью IDE

+500
Более того, и doxygen это предпочитает :). А он незаменим, когда приходится разбираться с плохо документированными проектами. Но если такой проект хорошо спроектирован в смысле ООП (классы хорошо отображают сущность бизнес-задач), то вот например такая картинка yetanotherquant.com/...​ngine__inherit__graph.png :) мне уж о многом говорит.

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

auto value = Class(arguments);

чем это вообще могло быть удобнее и читабельнее «классического»

Class value(arguments);

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

И это только один довольно самый яркий пример такого «принципа строго линейной крайней ограниченности». По моему нескромному мнению «новые стандарты» как раз дают такую «свободу где разгуляться руки из ж.» (к) (тм)

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

А почему некоторым нравится писать так — можете погуглить «almost always auto».
Крайне спорный стиль, особенно если им злоупотреблять, но кто-то находит его красивым. Слева переменная, справа тип и аргументы конструктора, всё разделено.
Можно провести параллель со старым
typedef bool(*PredicatePtr)(const Widget&);
и новым
using PredicatePtr = bool(*)(const Widget&);

И если кто-то предпочитает один стиль другому — он не тупее (и не умнее) вас, и это не значит, что он что-то понимает в языке меньше вашего или не умеет писать код по-другому. Это просто вкусовщина.
Вы б ещё о расстановке фигурных скобочек поспорили. Или похоливарили на тему east const / west const.

А в команде / на проекте должен быть общепринятый кодстайл, которому все следуют, и в котором такие моменты прописаны.

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

а я согласен с Алексом

Class value(arguments);

— сразу видно размещение на стеке

auto value = Class(arguments);

а вот это вот легко перепутать с

auto value = new Class(arguments);

разница огромна, согласитесь

там ещё и фишка в том что:

 auto a = A(100);
 auto b = B(100);
 ...
 a = B(200);

— просто потому что B(...) это функция. А может и А )) х.з.

ЗЫ: кстати вот хорошо вот взять тот же ж C# там с этим проще таки new и без вариантов и всё понятно и однозначно а си++ и туда не пришёл потому что задуман изначально не туда и вообще от этого уходит от простоты понятности и однозначности вот возьмём скажем то что сегодня здесь уже обсуждалось inline static как

class SomeOne
{
  inline static int s_ = 100;
};

Вот объясните мне зачем там «inline»?

Фишка вот в чём запись вида

class SomeOne
{
  static int s_ = 100;
};

— она уже совершенно однозначна прочесть её как-либо по-другому уже нельзя но записать так всё равно нельзя можно только «через inline» хотя вот смотрите «следи за рукой» (к) (тм)

class SomeOne
{
  static const int s_ = 100;
};

— и уже можно!

ОК это всё здорово а теперь объяснить это можно? Получается там есть какая-то «глубокая разница» а какая? И главное а зачем!?

И это при всём при том что

class SomeOne
{
  int s_ = 100;
};

— вуаля и снова можно!!! Но зачем!!!???

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

Вот это и есть реальные реалии современных стандартов си++.

Вот смотрите какая красивая кривоногость костыльная криворукость таки да в новом стандарте emplace_back() на контейнер возвращает ссылку на свежедобавленный элемент это здорово это реально весьма и весьма логично дёшево надёжно и практично и даже эстетично! но есть нюанс...

... потому как push_back() этого #внезапно _не_ делает. В чём логика такого хитрого хода глубины глубин сиплюсплюсной передовой мысли?

Но даже это ещё не всё потому как тайна глубины глубин на самом деле глубоко сокрыта от юных неокрепших падаваном претендующих на наличие вкуса (к) (тм) просто потому как

  Calss c;
  v.push_back(c);
  v.emplace_back(c);

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

Поэтому надо использовать фигурные скобки для инициализации:
auto a = A{100};
:)

Вспомнил весёлый доклад на эту тему: www.youtube.com/watch?v=7DTlWPgX6zs

Поэтому надо использовать фигурные скобки для инициализации:
auto a = A{100};

:)

A a{100};

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

A a{100};

Лично я так и предпочитаю писать. Я же сказал, что я сам не фанат стиля «almost always auto». Просто показал, как можно минимальным количеством правок изменить код «auto a = A(100)», чтобы стало однозначно понятно, что A — класс, а не функция.

«новые стандарты» прямо поощряют «вкусовщину» читай «отсебятину».

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

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

Это при условии, что в команде такой стиль уже есть....

Ого, сколько дописали. И, самое смешное, какие выводы сделали. «Не разбираюсь, но авторитетное мнение выскажу.»

это вообще глубоко одинаковый код и тут как-либо «встревать в намёки якобы одинаково зачем же ж так?»

Слушайте Майерса, если хотите понимать, в чём разница между emplace_back и push_back. Это не одинаковый код. Хотя в каких-то случаях может сводиться к таковому. Смотря какие элементы хранятся в векторе и что передаётся на вход в каждую из этих функций.
www.youtube.com/watch?v=smqT9Io_bKo
Если на вход передаётся элемент x такого же типа, что и элементы контейнера, то следует использовать push_back — emplace здесь будет тавтологией.

... потому как push_back() этого #внезапно _не_ делает. В чём логика такого хитрого хода глубины глубин сиплюсплюсной передовой мысли?

В том, что пушим мы в вектор какой-то ранее существовавший объект. С которым всё, что нужно было сделать, мы могли сделать и до вставки в вектор.
А эмплейс конструирует новый объект в памяти этого вектора (принимая на вход любые допустимые аргументы его конструктора) — и для него может понадобиться какая-то дополнительная инициализация после создания.
Поэтому для пуш_бека смысла возвращать ссылку меньше, чем для эмплейса.
Хотя согласен, что для консистентности могло бы допилить и это.

class SomeOne
{
inline static int s_ = 100;
};

Вот объясните мне зачем там «inline»?

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

Альтернатива — только объявить (без инициализации) static переменную в хедере, а определить (уже с инициализацией) в *.cpp-файле.

Кому лениво выносить определения в *.cpp (или, возможно, они не хотят экспортировать символ из библиотеки) — используют inline.
Это было применимо к функциям уже 100500 лет. Вот сейчас добавили то же самое для переменных.
Что сложного?

Фишка вот в чём запись вида

class SomeOne
{
static int s_ = 100;
};

— она уже совершенно однозначна прочесть её как-либо по-другому уже нельзя но записать так всё равно нельзя можно только «через inline» хотя вот смотрите «следи за рукой» (к) (тм)

class SomeOne
{
static const int s_ = 100;
};

— и уже можно!

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

Ну и да, сравнили const с изменяемой переменной...
Если вам эта s_ нужна как константа — незачем было вообще пытаться объявлять её как не-const. На const действуют несколько другие правила линковки. И так было всегда.

С const действительно всё будет в порядке без определения, пока вы не попытаетесь взять её адрес где-нибудь в коде. Если взятие адреса встретится — линкер снова будет требовать определение.
И опять же, так плюсы работали уже давно, задолго даже до C++11.

И это при всём при том что

class SomeOne
{
int s_ = 100;
};

— вуаля и снова можно!!! Но зачем!!!???

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

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

Резюмируя:

Вот это и есть реальные реалии современных стандартов си++.

Это и есть реальные реалии современных «ниасиляторов» C++, которым просто лень раз в три года посвятить пару вечеров чтению статеек / прослушиванию лекций о новом стандарте. А также доразобраться с некоторыми «пропущенными» правилами языка, которые существовали ещё с 1998 или 2003 года.

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

нет. инлайн перед функциями скорее похож на дефайн с функцией — вставляет код функции вместо вызова функции

Неа. Это определение, которое дают студентам на первом курсе. По факту inline на фактический инлайнинг влияет очень слабо, и в основном используется именно ради того, что я написал: чтобы вставить реализацию функции прямо в хедер-файл, позволив включать её в разные единицы трансляции многократно.

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

неиспользую функции используй классы там всё подряд писать можно причём давно и «с каропки» причём это же ж рассово верный подход просто потому как си++ это же ж ооп ))

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

ЗЫ: причём именно конкретно что в других местах оно конкретно таки используется именно что «вариант без inline» и это прекрасно работает никакой «неоднозначности» не возникает вопрос именно в том что вот конкретно ты именно так «как и следует из морали» сидишь и конкретно «придумываешь свои мысли а зачем так делать» вот конкретно по этому поводу ну ещё можно списать это на «вкусовщину» а вопрос и «мораль» именно в том что они криво и незачем и да в конкретном случае таки именно «и можно _только_ так».

Вот опять же ж почему для static const можно так и можно так и можно так а вот для чистого static уже надо писать либо «только inline» либо «по-старому»?

неиспользую функции используй классы там всё подряд писать можно причём давно и «с каропки» причём это же ж рассово верный подход просто потому как си++ это же ж ооп ))

Унылая шутейка за 300. Нужны и классы, и внешние функции.
А C++ — не чисто ООП-язык, хоть и эту парадигму он тоже поддерживает.

Вот опять же ж почему для static const можно так и можно так и можно так а вот для чистого static уже надо писать либо «только inline» либо «по-старому»?

Я пытался это выше объяснить. Больше расписывать не вижу смысла. При желании сам сможешь найти и почитать.

Только, если будешь читать, начни с C++98 и правил линковки для const- и не-const объектов.
Потом про inline-функции и то, как они позволяют «обойти» One Definition Rule (всё ещё 98-ой стандарт).
И только после этого — про inline-переменные из C++17. Тогда должно стать понятно.

Я пытался это выше объяснить. Больше расписывать не вижу смысла. При желании сам сможешь найти и почитать.

Только, если будешь читать, начни с C++98 и правил линковки для const- и не-const объектов.
Потом про inline-функции и то, как они позволяют «обойти» One Definition Rule (всё ещё 98-ой стандарт).
И только после этого — про inline-переменные из C++17. Тогда должно стать понятно.

прикинь а я всё же ж нашёл в чём цимес а цимес в default constructor для static class value и чтобы записать его таки и приходится писать

class C1 { <i>inline</i> static S1 s1_; }

потому что запись

class C1 { <del>inline</del> static S1 s1_; }

в данном случае _действительно_ означает совсем другое а более конкретно в первом случае это

class C1 { <i>inline</i> static S1 s1_{}; }

а во втором просто static member definition без static member instantiation.

А всё что ты написал со ссылками на ODR ерунда да ))

А всё что ты написал со ссылками на ODR ерунда да ))

Нет, это не ерунда. Это главное.

А то, что ты написал сейчас — уже следствие.
Естественно, что static без inline в таком контексте будет только объявлением, но не определением — определение (инстанциация) должно быть в *.cpp’шнике, и вот в нём уже и вылезет то самое «{}» (если не написать что-то другое в качестве инициализирующего выражения).

(фейспалм) а я что сказал?

инлайн перед функциями скорее похож на дефайн с функцией — вставляет код функции вместо вызова функции

Здесь, как я понимаю, речь шла про фактический инлайнинг («как дефайн») — то есть вставку кода функции непосредственно в место вызова. А я сказал о совсем другом.

похож на дефайн

это значит, что код замещается. просто при дефайне код замещается во время препроцессинга, а а при инлайне — во время компиляции, afaik

При «фактическом» инлайнинге — да. Но ключевое слово inline к этому имеет довольно косвенное отношение, и на самом деле оно в первую очередь нужно для другого: оно позволяет обойти One Definition Rule для функций (и, начиная с C++17, переменных), определения которых содержатся прямо в хедере. Собственно, об этом я и говорил.

ты мне про дефиниции, я тебе про имплементацию

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

Ещё раз: слово inline на инлайнинг мало влияет и основная цель использования этого ключевого слова вовсе не в этой оптимизации.
Неважно, будешь ты называть это «дефиницией» или «имплементацией», факт остаётся фактом. Функция (не темплейтная) с реализацией в хедере, не помеченная словом inline, даст ошибку линковки при попытке включить этот хедер в более чем один cpp’шник. Inline позволяет это обойти, не вынося тело функции в отдельный cpp-файл.
То же самое касается переменных в 17 стандарте.

Функция (не темплейтная) с реализацией в хедере, не помеченная словом inline

sic!

Функция (не темплейтная) с реализацией в хедере, не помеченная словом inline, даст ошибку линковки при попытке включить этот хедер в более чем один cpp’шник.

Дай угадаю почему? Наверное потому, что как макрос по сути, inline не имеет точки входа и соответственно не попадает в таблицу символов?

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

Линкер не настолько тупой. Он выдаст ошибку, если вы попытаетесь его обмануть и включите разные функции под видом одной в разные cpp’шники.
Функция должна быть одинаковой во всех единицах трансляции — поэтому то, какой из скомпиленных её экземпляров выбрать, не играет роли.

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

Линкер не настолько тупой. Он выдаст ошибку, если вы попытаетесь его обмануть и включите разные функции под видом одной в разные cpp’шники.

не выдаст. он тупой. сам решит какую брать. см. ODR ))

ЗЫ: причём там даже никакого особого «сам решит» и нет почти 146% он тупо возьмёт самую крайнюю тупо по проходу по списку линкуемых объектников.

Функция должна быть одинаковой во всех единицах трансляции — поэтому то, какой из скомпиленных её экземпляров выбрать, не играет роли.

кому должна? ))

не выдаст. он тупой. сам решит какую брать. см. ODR ))

Ну да. Строго говоря, он не обязан. Это уже вопрос quality of implementation.
Стандарт просто говорит, что это undefined behavior (stackoverflow.com/...​fferent-translation-units).
Я чего-то уже думал, что линкеры сейчас поумнели и умеют проверять такие вещи во время сборки, и хотя бы ворнинг выдают в случае обнаружения дичи (может, какие-то из них в последних версиях уже так делают? хотя вот проверил на 2017 студии, тулсет v141, — и правда, там линкер тупой)

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

Ну да. Строго говоря, он не обязан. Это уже вопрос quality of implementation.

Это вопрос того, что если работать в рамках конкретно M$, то «в моем окружении работает».
А вот когда вопрос встает о пачке разнородных, и как правило, уникальных библиотек, начинаются очень веселые вещи.
Которые и заставляют скептически смотреть на щенячьи восторги по поводу букета близких, но все-таки разных стандартов.

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

Не вижу прямой связи между новыми стандартами и этой проблемы с inline-функциями.

Не inline, а вся пачка нестандартизировнных деталей, которые внезапно решили стандартизировать.

Смотря как стандартизировать.
С теми же атомиками получилось неплохо, как по мне.
Учли особенности практически всех архитектур, чтобы дать программистам возможность выжать максимум из целевой платформы, не прибегая к нестандартным средствам.
(На всякий случай: речь именно про атомики, а не треды.)

А если появится новая платформа? Сейчас новый SoC сделать, как два пальца об асфальт, а atomic завязан даже больше на контроллер памяти и кэш, чем на ядро.

А если появится новая платформа?

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

И для неё будет недостаточно существующих мемори ордерингов?

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

Было бы интересно почитать про то, почему плюсовые атомики несовершенны.

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

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

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

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

лет 5 как избегаю плюсов, и наблюдаю такие же тенденции в сообществе

На всяких конференциях, бывает, рассказывают и обратное. Мол, плюсы в эмбеддеде набирают обороты в последние годы.
Хотя понимаю, что конференции не показатель реальной ситуации в индустрии.
Впрочем, как и опыт отдельно взятого человека.

Как бы не случился нишевой язык для HFT и геймдева.

Пока на рынке достаточно плюсовых проектов, не связанных с HFT или геймдевом.
А что там будет лет через 5-10, гадать бессмысленно.

На всяких конференциях, бывает, рассказывают и обратное. Мол, плюсы в эмбеддеде набирают обороты в последние годы.

Плюньте им в лицо. Снижают до нуля и в эмбеддед и в системном программировании. В отличие, например, от Python, доля которого растет.

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

Мол, плюсы в эмбеддеде набирают обороты в последние годы.

не знаю де там набирають, мій досвід показує, що те що на писано на плюсах через деякий час траху із сотвореним подєлієм рєшають переписувати ілі на чистом С ілі на Пітон із визовами С бібліотек, ілі на Го ілі на Руст

ілі на Го ілі на Руст

мечты, мечты...

это реальна жиснь,
чи от ти думаэш шо от я от нехфыг дэлать подсыв на руст.
ылы пайтон читав по ночам, шоп перепылыть мультедыа стрымер на ффмпег с ЦПП на шото получчэ?

ылы пайтон читав по ночам, шоп перепылыть мультедыа стрымер на ффмпег с ЦПП на шото получчэ?

зачем? какой нахрен пайтон в мультимедии? вы там вообще ребята с дуба рухнули?

пайтон який дьоргає АРІ ffpmeg, але ж приплюснуті ізобрітають собствінний лісапєт

ты хоть читаешь, что ты пишешь?
по твоему дергать сишный апи из пайтона это натурально, а из плюсов — лисапет?

не так, на С++ чувак писав моноліт, який ще «для оптимізації» і інтеграції ASM вимагав «чисто Інтел» компілятор, що в заіпало менеджмент, який відпарив далеко приплюснотого.
Далі було прийнято рішення переписати і моноліт замінити на сервіси, для більшості з яких вистачало дьоргнути АРІ ффмпега, і лише одну фічу пришлось заімплементити на чистому С, так як не було іншого варіанту.
При цьому працювало краще чим приплюснута шняга.

вимагав «чисто Інтел» компілятор

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

одна й та сама історія із приплюснутими на ембедед: то що написано на С++ тре переписувати ...
мабуть таки проблема або з С++ або із приплюснутими.. хтось згвалтував їм міски... для ембедеда вони не придатні

может это чтото у вас в консерватории не так?

тада, у ембедеді щось не так, а в приплюснутих так (манямірок++)

ну это конечно изврат и частный случай.

та конечно «частный» плюсовики все такие! ))

всё так ты снова всё прав ))

ЗЫ: alenacpp.blogspot.com

а че не на яве или питоне, прости госспади

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

о боже, может меня похитят инопланетяне, куда нить с этой планеты

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

Ну и где? Я смотрю, что на gcc оно использует builtin для atomic операций, которые full barrier. Нихрена не оптимизированные под целевую платформу.

Где вы это смотрите? Можно фрагмент кода?
И в каком смысле не оптимизированные?

Я смотрел libc++ от llvm (fetch_add), скомпилированную под gcc — оно свалилось в билтины, посмотрел gcc, оно выдало:

mov edx, OFFSET FLAT:global
lock xadd QWORD PTR [rdx], rax

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

Можно поподробнее для тех, кто в основном пишет под x86 и ни о чём сложнее ARM’а и PowerPC не читал?)

Что будет оптимально вместо lock’а в случае fetch_add, если memory_order, например, relaxed?
И при каких типах маппинга памяти lock’и здесь неоптимальны (а при каких оптимальны)?
Допустим, на таком примере: godbolt.org/z/UCWkkx

Проблема неоптимальности текущих атомиков всплывает только с этими некоторыми маппингами памяти, или вы видите также другие проблемы в их API?

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

Можно поподробнее для тех, кто в основном пишет под x86 и ни о чём сложнее ARM’а и PowerPC не читал?)

Кстати, на PowerPC оно свалилось в gcc built-in’ы.

Что будет оптимально вместо lock’а в случае fetch_add, если memory_order, например, relaxed?

А хоть на что-то memory_order влияет под x86? Я поверхностно глянул и ничего не обнаружил.

Проблема неоптимальности текущих атомиков всплывает только с этими некоторыми маппингами памяти, или вы видите также другие проблемы в их API?

Как по мне они сильно перестраховочные, чтобы работало везде, а значит, не оптимально. Я бы посоветовал глянуть Intel TBB и их реализацию.

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

Тут дело ещё не столько в маппингах (в них тоже), сколько в организации кеша процессора. Например, x86 в core i, когда все ядра на одной подложке использует глобальный cache lock даже не для атомарных операций, как INC, ADD, XADD, делая их по сути атомарными. Правда они заявляют, что LOCK во многих таких случаях игнорируется, но не во всех. Я когда-то экспериментировал и получил какие-то грустные значения — скорость fetch_and_add() порядка 7 миллионов операций в секунду при конкурентном доступе с двух ядер и порядка 50-100 миллионов при отсутствии конкурентного доступа. В тоже время lock ещё додавал тормозов, хотя и небольших, но заметных.

А хоть на что-то memory_order влияет под x86? Я поверхностно глянул и ничего не обнаружил.

На операции чтения не влияет. На операции записи — при дефолтовом (и самом строгом) seq_cst ордеринге добавляет полный барьер. Более ослабленные ордеринги вроде также не влияют.

Как по мне они сильно перестраховочные, чтобы работало везде, а значит, не оптимально. Я бы посоветовал глянуть Intel TBB и их реализацию.

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

Возможно — если вы говорите, что это API приводит к неоптимальному коду, — это API стандартизаторам ещё нужно расширять, добавляя новые варианты использования? Или при нынешнем дизайне оно уже заведомо провальное?

Или, возможно, здесь скорее должны помочь какие-то специфические ключи компилятора, если речь идёт об отдельных (относительно не часто встречющихся) архитектурах?

Мне более интересно: как должен выглядеть оптимальный асм для того же примера с relaxed инструкцией fetch_add, раз lock там избыточен? Какими нестандартными средствами его можно достигнуть на том же GCC?

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

Не вижу прямой связи между новыми стандартами и этой проблемы с inline-функциями. Она должна решаться на стороне производителей компиляторов/линкеров в первую очередь.

Угу.. при этом на стороне всех компиляторов и линкеров, и при этом одинаково. Что собственно и произойдет, не далее чем в ближайшие лет 5, скорее всего.

Не обязательно одинаково. Лишь бы помогало. Цель-то у человека будет исправить этот код, убрать неодинаковые копии этой инлайн функции. А не переносить подобную дичь между разными платформами и компиляторами, надеясь на какую-то консистентность.

Не угадал.

Слово inline с фактическим инлайнингом почти не связано. Оно нужно для другого.

Да, оно может повышать приоритет инлайнинга для компилятора (см. www.youtube.com/watch?v=GldFtXZkgYo) — но никаких обязательств в этом плане не накладывает.
Функция, отмеченная inline, на усмотрение компилятора может быть и не заинлайнена в каком-то случае. И если хотя бы один такой случай был, то в таблицу символов она таки попадёт. У inline-функций по умолчанию external linkage, а не internal, в отличие от функций из безымянных неймспейсов / static функций, которые в таблицу символов действительно не попадут.

Функция, отмеченная inline, на усмотрение компилятора может быть и не заинлайнена в каком-то случае.

зависит от уровня оптимизации. что компилятор сделает на -O0 ?

На -O0 наверняка вообще не будет инлайнить. Будет вызывать inline-функции «по-честному».
Можно поиграться здесь: godbolt.org/z/4wFor5

Нет, если inline сработал, то не попадает. Другое дело, срабатывание зависит от фазы Луны, т.е. простите от места в коде, размера функции, конкретного компилятора и полдесятка различных ключей оптимизации.
Подозреваю inline в хедере автоматически получает флажок always_inline.

Подозреваю inline в хедере автоматически получает флажок always_inline.

уже нет, к сожалению

уже нет, к сожалению

Учите Go детишки.

зачем? ГОвнокодить и на плюсах можно

если inline сработал

Он всегда «срабатывает». Просто нужно понимать, как именно он работает:
1) как средство для обхода ODR, чтоб можно было разместить определение функции (и переменной, начиная с C++17) в хедер-файле, без необходимости выносить его в .cpp’шник (то, о чём я многократно писал выше) — основное использование;
2) как хинт(!) для компилятора о том, что ему «стоит рассмотреть» эту функцию для встраивания («фактического» инлайнинга).

А так-то да, фактический инлайнинг зависит от перечисленных критериев, так и есть.

Подозреваю inline в хедере автоматически получает флажок always_inline.

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

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

А где я говорил за стандарт?
Вобще то что такой существенный момент не стандартизируется, я бы не отнес к достоинствам языка.

В языке много неконсистентностей, увы. Которые не исправляют, чтобы не ломать обратную совместимость.
Уже поздно менять смысл слова inline — остаётся запомнить, как оно на самом деле соотносится с настоящим инлайнингом, и зачем нужно на самом деле (собственно, inline переменные из C++17 этот смысл и подчёркивают).

А сейчас стандартизировать нужно новые атрибуты, которые придут на замену компиляторозависимым фичам вроде __attribute__((always_inline)).
Как, например, [[gnu::always_inline]] (en.cppreference.com/...​w/cpp/language/attributes)

Мало костылей — давайте добавим еще один.

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

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

Тогда как дифференцируются инлайны в хедере от всех остальных?

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

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

У меня предположение более простое — хедерный инлайн, если не ошибаюсь, живет только внутри декларации класса. И могу даже предположить, что если декларация класса внутри .cpp компилятор отработает его также. Что собственно и происходит в препроцесснутом файле.
Собсно надо всего лишь выделить час времени и скомпилировать пару хеллоборлдов.

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

Ну да. Все макросы раскрыты, все инклуды вставлены. Каждый .cpp файл разросся раз так в 10. Как компилятор отличит inline-ODR от обычного POC-inline ?
Хороший вопрос на собеседование кстати.

Ну, чем отличается inline в чистом C от плюсового inline, я не помню. Возможно, есть какие-то отличия в правилах линковки.

Но про плюсы могу сказать, что компилятор/линкер не отличает «POC-inline» от «inline-ODR».
Он видит символ — функцию или (начиная с C++17) переменную — видит, что этот символ обозначен как inline, и начинает на этапе линковки вырезать все определения этого символа, кроме какого-то одного (какого именно — никто не уточняет, поэтому и важно, чтобы все скомпиленные определения были одинаковыми).

инлайн в С появился в С99 и работает точно так же. я думаю POC это про дефайны.

Не слышал такого определения :( И что-то оно плохо гуглится. Можно ссылку, или самому парой слов описать, что это? Типа, функция, которая всегда фактически встраивается в место вызова и никогда не будет появляться в таблице символов («как макрос»)?

мне кажется вопрос о пределах работы ODR намного интереснее.

Нет никаких «хедерных» и «не хедерных» инлайнов. Потому, что в плюсы пока что не завезли нормальную систему модулей (ждём C++20). Всё, что сейчас есть — старое сишное «#include»-легаси.

А что делает #include? Она просто копипастит текст одного файла в другой. Ничего более сложного там нет.

Поэтому неважно, напишете вы инлайн функцию в хедере и заинклюдите его в два разных .cpp’шника, или же тупо вручную вкопипастите эту функцию в каждый из этих файлов.

Это, кстати, касается чего угодно, что размещается в хедерах, а не только inline функций.

С объявлениями класса inline напрямую не связан.
В определениях класса любая функция, реализована прямо в теле этого класса, становится неявно inline.

Потому, что в плюсы пока что не завезли нормальную систему модулей (ждём C++20). Всё, что сейчас есть — старое сишное «#include»-легаси.

И эти люди спрашивают, почему их не хотят видеть в embedded ?

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

И эти люди спрашивают, почему их не хотят видеть в embedded ?

Во-первых, я ничего на эту тему не спрашивал.
Во-вторых, у меня есть информация, что в некоторых компаниях, занимающихся embedded, видеть современные стандарты плюсов очень даже рады. Она не совпадает с вашим личным опытом — окей. Не думаю, что вы можете говорить за всех.

В-третьих, как можно в почти 2к19 не понимать, что система инклюдов — кусок засохшей какашки мамонта? Да, ничего лучшего пока не завезли, но это не значит, что так и должно быть.
Из-за этой системы инклюдов один и тот же код вынужден компилиться по 100500 раз (в каждом .cpp’шнике, который прямо или косвенно включает в себя хедер) — и потом бедному линкеру приходится всю эту помойку разгребать.
Именно по этой причине плюсовые проекты так долго собираются. И модули должны решить эту проблему.

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

Принесут ли модули какой-то рантаймовый оверхед, недопустимый для эмбеддеда, я пока не знаю.

не должны. я так понимаю, это типа тпу в трубопаскале

у меня есть информация, что в некоторых компаниях, занимающихся embedded, видеть современные стандарты плюсов очень даже рады.

серйо?
там дальше РОС (пруфофконцепт) не йде і все вмирає не доживши до сапорта

вы вот сейчас сразу за все-превсе ембеддед компании ответили?
кстати, традиционный вопрос — дефайн ембеддед

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

спасибо что хоть честно признался

тобі уже кілька раз різні люди писали, а ти «а шо таке ембедед» і «почіму С++ не нужен в ембеддед»

тобі уже кілька раз різні люди писали

писали что?

а ти «а шо таке ембедед»

ты же понимаешь разницу между MCU с 16к памяти и какойнить Acore с 8ю ядрами и гигазами рама? да? и то и то как бы эмбеддед.

і «почіму С++ не нужен в ембеддед»

где я такое писал?

Видел живьем людей тащащихся от TMP в трушном эмбедеде. Только как их поделие работает я не понял, но это уже ньюансы :) Надо будет видосик пересмотреть.

Хотле поднять тему компайл-тайм дебагера.... да постеснялся.

дефайн ембеддед

Те устройства, где софт такая же неотъемлемая часть функционала, как и электроника или механика и недоступна к управлению конечным пользователем.
Реле времени на микроконтроллере это или 8-процессорная нода мобильной связи — безразлично.

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

Я уже видел не одну компанию, которая не зная броду решала полезть с С++ в эмбеддед, а также громкие факапы, которыми все кончалось.
Т.е. поначалу было все хорошо, а потом приходили любители темплейтов и прочих усовершенствований. А отлаживаться в ssh-консоли это не совсем то, что в Visual Studio.

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

Mike, Андрей (flyman), Илья — имеют по 10++ опыта в этой теме.

В-третьих, как можно в почти 2к19 не понимать, что система инклюдов — кусок засохшей какашки мамонта? Да, ничего лучшего пока не завезли, но это не значит, что так и должно быть.

Засохший конечно. Только вот намертво присохший к миллиардам строк существующей кодобазы.
Кстати это и есть резон появления новых языков типа Rust (ни разу не фанат)

Именно по этой причине плюсовые проекты так долго собираются.

Продуманная система зависимостей лечит это.

Принесут ли модули какой-то рантаймовый оверхед, недопустимый для эмбеддеда,

Оверхед в современном эмбеддеде это вторично. В конце-концов STM8, на котором сейчас делают умные розетки это развитие кристалла, на котором был построен Apple II.
А вот configuration management — принципиален. И гарантия того, что один и тот же код будет вести себя одинаково на пол-десятке архитектур разной разрядности и разной endianess.
И, ах да, туда тянется еще длинный хвост библиотек привязанных к хардвару, сжатию/кодированию или протоколам связи родом из 90-х, которые должны стабильно работать.

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

Ну так кто этой компании виноват, что она
1) полезла с C++ в эмбеддед не зная броду;
2) набрала тех самых «любителей темплейтов и прочих усовершенствований» (не иначе как из «ясельной группы» падаванов Алекса Фогола), и не проследила за тем, что они творят?
Сами себе злобные буратины.
И это никак не связано с C++ как таковым. С любым инструментом можно накосячить, если бездумно фигачить непонятно что.
А если понимать, что и зачем ты делаешь, и не злоупотреблять фичами ради фич — то и «темплейты и прочие усовершенствования» (там, где они реально уместны) не будут чем-то плохим.

Mike, Андрей (flyman), Илья — имеют по 10++ опыта в этой теме.

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

Только вот намертво присохший к миллиардам строк существующей кодобазы.

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

Продуманная система зависимостей лечит это.

Я бы сказал, обходит, а не лечит. И то, только частично.

А вот configuration management — принципиален. И гарантия того, что один и тот же код будет вести себя одинаково на пол-десятке архитектур разной разрядности и разной endianess.

К архитектуре и endianness модули не имеют отношения. Лишь бы под эту целевую платформу существовал компилятор, умеющий в модули.
Будет ли код вести себя одинаково на этих архитектурах — зависит от того, как сам код написан. И не должно зависеть от того, как этот код будет распихан по модулям (unless в компиляторах будут специфические связанные с этим баги).

И, ах да, туда тянется еще длинный хвост библиотек привязанных к хардвару, сжатию/кодированию или протоколам связи родом из 90-х, которые должны стабильно работать.

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

Ну так кто этой компании виноват, что она

проблема в тому, шо «ми крутие плюсатніки» а «ви тупі Сішники» , а далі «шото пошло не так...»

Ну так кто виноват, что набрали «крутых плюсатников» вместо нормальных девелоперов? «Крутых», которые не понимают, что они делают, меньшинство. Но набрали именно их, и позволили им всё сломать. Сами виноваты. По ходу действительно тупые сишники :)

кто виноват, что набрали «крутых плюсатников» вместо нормальных девелоперов

як хто, той хто приймав рішення

По ходу действительно тупые сишники :)

а їх мнєнієм ніхто не інтересувався

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

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

набрать «миддлов» сишников, которые на деле и до джуна бы не дотягивали

ну спробуй

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

Не понимаю, чем тебе не нравится. Чисто инжерные вопросы в отличие от схоластики про абстрактный класс и интерфейс.

Это какие? Долго по топику искать, что они там спрашивали. И еще, знание теории не сильно связано с тем, как человек работает (есть четыре варианта — из них только 2 подходят).

Ну так кто этой компании виноват, что она
1) полезла с C++ в эмбеддед не зная броду;
2) набрала тех самых «любителей темплейтов и прочих усовершенствований»

Культура С++ сообщества обязывает использовать «всю мощь языка» не задумываясь о последствиях.
См. название топика.

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

Тут не думать надо. Тут маст. И смешивание в одном проекте модулей с инклудами ведет к одному — появлению питательной среды для ошибок на ровном месте. Там где предыдущие 40 лет все работало нормально.

Культура С++ сообщества обязывает использовать «всю мощь языка» не задумываясь о последствиях.

Что? В С++ сейчас в основном старперы. Отсюда и так медленно все эти новые фичи внедряются. Полноценно стандарт юзать начинают лет через 10 после его выхода в свет.
Вот я включил поддержку 17-го только потому, что boost лень заюзать было. Добавить один ключик проще и быстрее, чем либу подключать.

Культура С++ сообщества обязывает использовать «всю мощь языка» не задумываясь о последствиях.

Только в голове тех, кто мыслит стереотипами. Это как говорить, что у сишников всё течёт и сегфолтится, а у джавистов вечно тормозит. Детский сад.

Тут не думать надо. Тут маст.

Естественно это маст. Я имел в виду, что они думают, как это сделать лучше всего.

И смешивание в одном проекте модулей с инклудами ведет к одному — появлению питательной среды для ошибок на ровном месте. Там где предыдущие 40 лет все работало нормально.

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

Цікаво, і чим це таким сакральним відрізняється дебаг в ssh-консолі від дебагу в студії?

студия подключается через консоль (только тссс!)

І, кажуть, остання й gcc нормально дебажить з коробки, хоча й стара могла — з платним плагіном.

Так в проде налету битики меняют, небось.

А написать HAL и дебажить на компе?

Если заказчик готов платить :)

По факту inline на фактический инлайнинг влияет очень слабо, и в основном используется именно ради того, что я написал: чтобы вставить реализацию функции прямо в хедер-файл,

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

а никто не говорил, что будет легко :)

Одно из моих ярких впечатлений за последнее время. Был на конференции где целых 3 доклада (считай по докладу в день) были на тему «а вот посмотрите как тут все страшно» и в аудитории куча бородатых дядек согласно кивают «да точно страшно же».

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

а никто не говорил, что будет легко :)

Вообще-то говорили. Когда 11 стандарт только зачинали говорили, что сделают язык проще... В результате родини не юниформный Юникорн инициализацию и «алвейс авто»... ну и иного чего полезного конечно..

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

Вот тут да, есть такое. Наверное потому, что не просто развиваются, а ещё и стараются сохранять компатибилити, а сохранять её надо аж на 40 лет назад...

Вообще-то говорили. Когда 11 стандарт только зачинали говорили, что сделают язык проще...

ну так кто мешает использовать только авто, а остальное как получиться?

нет, просто авто ещё ничего. А вот авто и списки инициализации — вот это уже что-то. Опять что-то...

auto x{666};
Это что такое? (а в разных стандартах оно разное!!)
Зато вот это одинаковое
auto x = {666};
но совсем не то что тебе бы хотелось.

Сама по себе идея авто — нормально. Авто везде — перебор.
Списки инициализации — интересная фигня. Списки везде — перебор.

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

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

Потому что «auto x = { 0 };» это дичь. Даже такой «задрот плюсов», как я, не знает (точнее, не хочет знать), какой тип у этой переменной. Может быть int, может быть std::initializer_list.
Майерс как-то рассказывал на одном из выступлений, что вроде даже между 11-ым и 14-ым стандартами тип этого выражения менялся.

Нет не меняется, ничего не меняеттся, я же пишу, везде все одинаково, везде

std::initializer_list

...
а вот

auto x{666};

вот это таки меняется. Только не между 11 и 14 а между 14 и 17... ну то есть говоря другими словами прямо по теперешней передовой границе адаптации фич стандарта в реальных проектах. с инишиалайзер листа на инт.... Поздравляю с наступающим uniform initialization :)

Да, немножко перепутал. Как я и сказал: я даже не хочу этого помнить. Большую часть «подводных камней» C++ я знаю хорошо, но вот эта конкретная фигня с «auto x{42}» — это то, что я не хочу даже пытаться запоминать. Сама эта строчка кода для меня выглядит как полный бред, не заслуживающий быть закоммиченным куда-либо. А значит и нет смысла вникать.

Кому интересно послушать про эту жесть — вот, нашёл таймкод: youtu.be/wQxj20X-tIU?t=1759
Кстати, лекция в целом очень полезная. Именно благодаря ей у меня в голове окончательно разложились по полочкам move-семантики, perfect forwarding и прочие темплейтные штуки.

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

Мы к примеру когда-то пару дней дебагали ситуацию где создание объекта компилятор таки проинтерпретировал как объявление функции.

Лучше бы вы писали на питоне или жабаскрипте. Меньше вреда бы принесли.

Я кстати пишу и на питоне и на жабаскипте. А тот код был написан чистым С++ с 25 годами сраного комерческого опыта, на тот момент. Снобизм свой поумерил бы.

Кто ж вам виноват, что с извращенцами работаете. Пиши проще и проблем в коде бeдет меньше. KISS.

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

Они и разрулили ещё в 11 стандарте, когда ввели инициализацию через фигурные скобки. С ней такой лажи не будет:
Foo bar(Baz()); // most vexing parse
Foo bar(Baz{}); // ok

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

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

С ней такой лажи не будет:

будет именно потому что за жОпу твёрдо и крепко держит

они уже не могут: поломают обратную совместимость.

и в результате современный си++ (к) (тм) да в говно.

будет

У меня не будет. На всех компиляторах (относительно свежих версий), с которыми мне доводилось работать, синтаксис «Foo bar(Baz{})» к локальному объявлению функции не приведёт. И стандарт требует того же.

именно потому что за жОпу твёрдо и крепко держит

Меня никто на работе за это место не держит. Не знаю, как там в других компаниях принято.

и в результате современный си++ (к) (тм) да в говно.

Что в говно(к)(тм)? То, что современный C++ уже поломал часть обратной совместимости? Ну да, есть немного. «register int i» больше не объявишь. Но комитет идёт на подобные изменения довольно медленно, неохотно и в очень ограниченном количестве мест.
Хотя я был бы не против, чтобы к C++20 они объявили локальные объявления функций как deprecated, а к C++23 ремувнули из стандарта. Ибо кто использует синтаксис «Foo bar(Baz())» для объявления внешних функций в локальном скоупе какой-то функции — извращенец, как по мне.

Но их работы выполняют разрабы компиляторов и выдают ворнинги в таких местах.

твое представление об Мире наивне мой юный падаван ))

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

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

Мы к примеру когда-то пару дней дебагали ситуацию где создание объекта компилятор таки проинтерпретировал как объявление функции.

А вот это как раз классика. Most vexing parse. С ним сталкивался за последние пару лет раза три или четыре.

Часто это просто описка програмера, но тем ни менее ворнинги компилятора нужно читать.

В том и проблема, что это не описка. Просто программер имел в виду одно, а для компилятора оно выглядит как нечто совершенно другое из-за одного крайне специфического правила парсинга C++.
И ворнинга там не будет. Там будет эррор, причём с довольно странным текстом. Кто раньше на практике с most vexing parse не сталкивался, может долго сидеть чесать репу над этой ошибкой.

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

Most vexing parse не новомодная, она была в языке всегда. И иногда код, содержащий эту каку, может выглядеть вполне себе простым и безобидным.

Но мне казалось, что компилятор об этом сейчас предупреждает

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

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

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

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

Да пофиг. Ошибки, что пишет компилятор в С++ часто находятся очень далеко от того места на которое указал компилятор.

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

ну справедливости ради если продристать 17 страниц текста ошибки то там таки в самом самой конце таки найдётся конкретное место откуда же ж он это сказал ))

откуда же ж он это сказал ))

«чем ты это сказал?» ©

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

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

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

да например? ))

ЗЫ: ерроры на шаблонный код «плюсов» уже вообще притча во языцех со времён Буста Да Святиццо Имя Его ))

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

Кто насрал? Где?
«Foo bar(Baz())» — человек захотел создать локальный объект bar типа Foo, передав ему дефолтно сконструированный объект типа Baz() в качестве аргумента конструктора. Это, по-твоему, насрал? Я не согласен, по мне оно выглядит довольно просто.

Или насрал в стандарте, что позволил такие объявления функций?
Тогда с этим я согласен, но эта сомнительная фича пришла в плюсы ещё из C: ideone.com/F8rZP9 — и ради обратной совместимости её не выбросили.

да например? ))

Можешь поиграться здесь: godbolt.org/z/BB1WTo
Но кланг меня приятно удивил. Даже отдельный ворнинг выдал в строчке с этим объявлением.
Помню, когда столкнулись на этом на прошлой работе на 2012 или 2013 вижуал студии — текст ошибки был гораздо более непонятным.

ЗЫ: ерроры на шаблонный код «плюсов» уже вообще притча во языцех со времён Буста Да Святиццо Имя Его ))

На это я отвечал выше. Да, там эрроры более непонятные, но к ним люди больше привыкли, т.к. видят их на порядок чаще, чем most vexing parse.

но иногда описываюсь на автопилоте

это же ж не руст тут надо тренировать свой мочевой пузырь и не описываться а то замкнёт.

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

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

ЗЫ: включая метаязык для шаблонов и метапрограммирования который вообще настолько «не си++» что отнять у него си++ и он тупо переносим куда угодно сам по себе.

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

например?

Сейчас за пять минут набросать пример с действительно непонятной ошибкой у меня не получилось. А больше времени тратить лень. Пока что ошибка действительно получалась довольно понятной: ideone.com/pk6M3D
Но когда мы около трёх лет назад столкнулись с этим в продакшене на более старом компиляторе вижуал студии — всё было гораздо менее очевидным.

Мы к примеру когда-то пару дней дебагали ситуацию где создание объекта компилятор таки проинтерпретировал как объявление функции.

зато швидко напедалили #хайлевелабстракшен

За 4 місяці. На місяць довше ніж мали б. А не наклепали б і проекту того не бачили би... А проект той був найкращим досі в моїй карєрі.

цікаво, яке може бути компабіліті із авто, якщо колись воно мало зовсім інший зміст

Ну ніяк, старе значення вбили, старі фічі таки деприкейтять.

Ключове слово static достатньо перегружене в C++ і частина цього хаосу перекочувала із старого доброго C.

На рахунок push_back — то тут варіанта 2: або його не захотіли ’апгрейдити’, або про це не подумали. І якщо таки мав місце бути другий варіант, то скоріше за все це ’наздоженуть’ у наступному стандарті (звісно, якщо комітет стандартизації буде в курсі, що є така ’проблема’). Ну наприклад як в C++11 тупо не додали make_unique, але додали в C++14.

Про це і йде річ, що стандарти не завжди породжують нові ризикові фічі, але й буває покращують уже обкатані фічі і їх використання стає більш простим і логічним. Ну як приклад ключове слово override — жили і без нього, але з ним код стає більш читабельним.

Ключове слово static достатньо перегружене в C++ і частина цього хаосу перекочувала із старого доброго C.

да оно используется аж в 2-х местах для определения static внутри единицы компиляции и для определения static member внутри класса собственно и всё всё как и раньше никакой «перегруженности» там не было и нет.

Дійсно все дуже просто:
1. static member
2. static method
3. static global variables in cpp file
4. static local variable inside a function/method
5. static function in cpp file

4. static local variable inside a function/method

ок my bad упустил static local variable

ЗЫ: на самом деле нет никакой разницы между методами и функциями )) но это секретЪ

ЗЫ: на самом деле нет никакой разницы между методами и функциями )) но это секретЪ

А как же мемберы, ну когда их запихнуть в структуру?

struct TheClass {
	void(*DoSomething)(struct TheClass* This);
	int i;
};

void TheClass_DoSomething(struct TheClass* This) {
	This->i = 100;
}

int main() {
	struct TheClass the;
	the.DoSomething = TheClass_DoSomething;
	the.DoSomething(&the);
}

Чистый сахарок’с ))

Чистый сахарок’с ))

Скорее бочка говна в ложке мёда %)

Скорее бочка говна в ложке мёда %)

вот за ооп щас абыдна была ))

ЗЫ: кстати инкапсуляция (к) (тм) ))
ЗЫ: и кажется немножечко полиморфизм но надо подумать...

ЗЫ: на самом деле нет никакой разницы между методами и функциями )) но это секретЪ

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

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

Ну а ещё можно вспомнить все gory details того, как устроены указатели на функции-члены. Их много видов и они гораздо сложнее, чем указатели на простые функции.
Предлагаю к ознакомлению любопытную статью, уже успевшую стать классикой (причём здесь даже никаких новомодных стандартов, 2005 год): www.codeproject.com/...​-and-the-Fastest-Possible
И дай бог, чтобы это вам на практике не пригодилось :)
Хотя я как-то работал на проекте, где использовались такие делегаты. Было весело.

Как минимум, обычные функции не могут быть виртуальными. Диспетчеризация виртуальных функций подразумевает выбор между несколькими конкретными функциями, которые могут реализовать один и тот же метод в зависимости от динамического типа объекта.
struct TheClass {
	void(*DoSomething)(struct TheClass* This);
	int i;
};

void TheClass_DoSomething(struct TheClass* This) {
	This->i = 100;
}

void TheClass_DoSomethingElse(struct TheClass* This) {
	This->i = 200;
}

void TheClass_MakeCppGreatAgain(struct TheClass* This) {
	This->i = 100500;
}

int main() {
	struct TheClass the_original;
	the.DoSomething = TheClass_DoSomething;
	the.DoSomething(&the);

	the.DoSomething = TheClass_DoSomethingElse;
	the.DoSomething(&the);

	the.DoSomething = MakeCppGreatAgain;
	the.DoSomething(&the);
}

Ну да, я это и имел в виду. Один «метод», который выражается через три разные функции. Я ж не говорю, что подобное нельзя написать на чистых сях :)
Более того, при ручной реализации можно более точно специфицировать механизм диспетчеризации. В отличие от того, что предлагают плюсы по дефолту.

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

Вообще, подходов к этой задаче существует большое множество. Мне сразу вспомнился Александреску, как он рассказывал про свой опыт «девиртуализации» (если я не ошибаюсь, в Фейсбуке): youtu.be/ea5DiCg8HOY?t=1872
А также вот этот замечательный доклад Луи Дионна: www.youtube.com/watch?v=gVGtNFg4ay0

метод належить класу, а хвункція так як би фрі

Ну можна і так сказати, але по факту в кожен нестатичний метод просто передається першим параметром вказівник на об’єкт (в python це явно роблять при описанні метода).

метод належить класу, а хвункція так як би фрі

Спорим я могу объявить метод «якый неналэжить класу»?

class C1 {
  virtual void Foo() = 0;
};
void C1::Foo() {}

чисто абстрактном жы ж ))

а вот это вот легко перепутать с

Не могу согласиться, лично я такое в жизни не перепутаю. У меня нюх на сырые операторы new в коде :)

лично я

сможете отвечать за всех?

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

А так-то естественно нет. Это невозможно. Как и вы не можете отвечать за всех, утверждая, что «auto x = Class()» легко перепутать с «auto x = new Class()».

Это просто вкусовщина.

«вкусовщина» это когда есть вкус а когда вкуса нет это просто банальное и общепринятое прикрытие безвкусицы.

Речь именно об том что чем дальше тем больше си++ это развивает и поощряет.

Причём настолько что даже придумали Rust ))

«вкусовщина» это когда есть вкус

Так он и есть. Просто он не совпадает с вашим и вам это не нравится.

чем дальше тем больше си++ это развивает и поощряет

Развивает? Да. В плане того, что даёт больше возможностей сделать одно и то же, причём у каждой из них будут свои нюансы.
Поощряет? Нет. Никто не заставляет ни вас, ни ваших «падаванов» использовать ту или иную возможность языка. Повторюсь: для этого должен существовать принятый в команде кодстайл и регулярно проводиться код ревью. Не поощряйте то, что на вашем проекте неуместно, вот и всё.

Причём настолько что даже придумали Rust ))

Много чего придумали (можно ещё D вспомнить), но плюсы так ничем из этого и не смогли заменить. И вряд ли уже смогут.

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

а ну ок я пас ))

но плюсы так ничем из этого и не смогли заменить.

Rust? ))

ЗЫ: и да ок я пас я эту ерунду проходил уже множество раз «результат» везде одинаковый я проверял ))

Rust? ))

Пока что не заменил. Многие его хайпят, ибо, действительно, язык избежал многих проблем C++. Но до популярности плюсов ему пока очень далеко.
Возможно, лет через 10-20 это изменится. Но сейчас о таком говорить рановато, как по мне.

флайман писал, что руст на 30% медленнее

Можно провести параллель со старым
typedef bool(*PredicatePtr)(const Widget&);
и новым
using PredicatePtr = bool(*)(const Widget&);

Можно спросить?
А как это будет работать в комплекте со старым добрым С?
Напомню, что фишка плюсов это совместимость со старой доброй сишной кодобазой?
Или вслед за потоками и файлами в std пойдет криптование, сжатие и прочие libcurl’ы ?

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

Напомню, что фишка плюсов это совместимость со старой доброй сишной кодобазой

Это одна из фишек плюсов. Которая на некоторых проектах может и не быть столь важной.

Как правило, никто не мешает взять взять старую добрую сишную либу (тот же libcurl) и заюзать её в плюсовом проекте, использующем последние новомодные фишки C++20.

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

вопрос там в том что вы применяете технику саму по себе в самих по себе «плюсах» чисто технически архаичную это вообще «чистый си» но при этом вы меняете typedef на using и заявляете «вуаля! теперь мы узаем си++ новый стандарт!» (к) (тм)

А смысла в этом вот конкретно в этом месте нет от слова вообще. Но ещё раз таки _да_ «но можно и так» (к) (тм) но нюанс и мораль именно в том что «а зачем?» (к) (тм)

это вообще «чистый си» но при этом вы меняете typedef на using и заявляете «вуаля! теперь мы узаем си++ новый стандарт!» (к) (тм)

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

А смысла в этом вот конкретно в этом месте нет от слова вообще.

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

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

Этот «злыдень» появился ещё на заре C++, когда только придумали классы и шаблоны.
А вас тут внезапно using и auto удивили. Тю :)

Я видел вообще терминальные случаи

А я видел противоположные терминальные случаи. Например, когда люди продолжали грызть кактус, оставаясь на C++98, отказываясь от банальнейшего std::unique_ptr и продолжая повсеместно использовать конструкцию std::vector (с владеющими сырыми указателями, естественно). Память текла как в ниагарском водопаде.

И какой из этого вывыод можно сделать? Что новые стандарты — зло? Или старые стандарты — зло?
Зло — это вот эти вот самые «терминальные случаи» — и неважно, в какую сторону повёрнута их «терминальность».

И какой из этого вывыод можно сделать? Что новые стандарты — зло? Или старые стандарты — зло?

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

Там не в использовании вектора была проблема. А в контроле за указателями, которые ранее получили через ручной вызов new и не удалили.

А в контроле за указателями, которые ранее получили через ручной вызов new и не удалили.

Это же ясельная группа, как тогда работают миллиарды строк С кода?

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

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

А когда ты сосредоточен на решении бизнес-задачи и спускаться на уровень низкоуровневых деталей нет необходимости (ничего перформанс-критикал там не было) — лучше таки юзать std::unique_ptr в таких случаях.

А когда ты сосредоточен на решении бизнес-задачи и спускаться на уровень низкоуровневых деталей нет необходимости (ничего перформанс-критикал там не было) — лучше таки юзать std::unique_ptr в таких случаях.

Война — фигня. Главное — маневры! Иначе переписать на жабе и забыть, раз ничего перформанс критикала там нет.

Иначе переписать на жабе и забыть, раз ничего перформанс критикала там нет.

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

Сравнили GUI с пальцем :)

Оверхед от unique_ptr’ов минимален, а в большинстве случаев вовсе нулевой, ибо всё прекрасно инлайнится.
Оверхед жабы... Ну, там бывает по-разному. Я не из тех адептов C++, которые утверждают, что жаба фигня и медленная. Но всё же разница есть.
А в проекте были другие перформанс-критикал места, написанные на плюсах и хорошо соптимизированные. Легче уже окружающие их классы написать на более высокоуровневых плюсах (возможно, с небольшим оверхедом, если он вообще будет), чем комбинировать зоопарк из технологий.

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

Но всё же разница есть.

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

как тогда работают миллиарды строк С кода?

переписываются на Rust? ))

ЗЫ: вообще-то в самом си++ тоже «мусорщика» никакого нет в самом runtime вся «магия с указателями» строго «вручную» читай «самописная только уже кем-то до нас».

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

Но в результате получаем «фишки» с которыми я например точно помню впервые столкнулся со стандартом 17 когда в коде кто-то написал shared_ptr по массиву ну да в 17-м это оказывается «уже можно скаропки» а в 15-м всё ещё не так но повозившись немного я таки сделал решение но потом продолжил расследование «странностей применения нового стандарта» и оказалось сперва а зачем там собственно shared_ptr если это больше никуда не передаётся? а в unique_ptr по массиву кстати можно сделать «уже скаропки» и уже на 15-м но вот незадача «а зачем?»

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

И вот в моей «ясельной группе» этот «новый стандарт» работает именно так что именно и ещё раз доказывает сабжевый товарищ выступлениями уже здесь в этом треде ))

что она точно позволяет так это _не_ думать

И что изменилось с C++98?
Взять тот же std::vector.
Люди тоже могут лепить его куда попало, в том числе и где достаточно простых массивов на стеке.
А могут понимать, что как именно он работает под капотом, в каких случаях он нужен, в каких нет — и использовать там, где это оправданно, экономя своё время и время тех, кто будет этот код читать.
Новые стандарты продолжают развивать язык ровно в этом ключе.

что именно и ещё раз доказывает сабжевый товарищ выступлениями уже здесь в этом треде ))

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

А свои предрассудки и додумки оставь для очередного кандидата в вашу «ясельную группу». Судя по твои рассказам, у вас там в основном таких и набирают, — а значит проблема не только в кандидатах ;)

Так це ж ваші падавани, ви ж їх скоріше за все самі і набрали (принаймні гонору у вас тут на сініор тім лід). То може треба брати на себе відповідальність за тих людей, які у вас в ’падаванах’ ходять.

Як на мене у вас достатньо клінічний випадок: ’всє п@#$си, а Я дартаньян!’. Всі навкруги рукожопи і тільки ви як атлант стримуєте поток людей з ’низчим інтелектом’, але деякі просочуються і поражають своєю недалекістю...

Повторюсь уже в N-ий раз, в сабжі було запитання чи є такі проекти на наших просторах. Все, крапка, а у вас бомбить як школоло

А в контроле за указателями, которые ранее получили через ручной вызов new и не удалили.

А причина этого — запутанные функции с многочисленными точками выхода. Иначе бы ловилось простейшими синтаксическими анализаторами.

Там и синтаксические анализаторы не использовали :)

Ладно, попробую немножко раскрыть свой поинт. Когда человек в принципе понимает, что он делает, он создает под задачу какой-то сет или пул динамических объектов и так же прибирает.
И даже если в спешке забыл — исправить это не большая проблема.
Другое дело костыли. Тут уже не упомнишь у кого какая область видимости, и надо вводить auto_ptr.
А потом оказывается, что auto_ptr проблему не решает и начинают плодится shared, uniq, weak и понеслось.
Причем код становится все менее очевидным и все сложнее отлаживаемым и на этом фоне небольшой оверхед на расстановку delete уже не выглядит таким страшным.

А потом оказывается, что auto_ptr

...deprecated

auto_ptr

Боже упаси. Их кривой конструктор копирования — абсолютное зло. И вектор auto_ptr’ов не будет вести себя адекватно (повезёт, если компилятор на такое выдаст ошибку).
Там, где раньше юзался auto_ptr, сейчас следует юзать unique_ptr.

shared нужен только если требуется разделять владение объектом с кем-то другим, и непонятно, кто последний будет ссылаться на этот объект, чтобы в конце его удалить. Или же если нужны weak-ссылки (т.е. чтоб дать возможность другому участку программы «спросить», не умер ли уже объект).

Короче, если архитектура не требует shared и владелец объекта однозначно понятен, стоит юзать unique — не ошибётесь.

Причем код становится все менее очевидным и все сложнее отлаживаемым и на этом фоне небольшой оверхед на расстановку delete уже не выглядит таким страшным.

Категорически не согласен. Разве что если человек ну совсем уже не привык работать с этими шаблонами.
У меня всё наоборот. И у команды, с которой я сейчас работаю, тоже. Код с использованием смарт поинтеров становится только более очевидным (т.к. сразу понятно, кто владеет, а кто просто ссылается; один там владелец или может быть несколько), отлаживается практически так же (любая IDE позволяет в режиме дебага заглянуть вовнутрь смарт поинтера и посмотреть на сырой указатель, лежащий внутри).

любая IDE позволяет в режиме дебага

Ключевое слово.

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

Беда С++, что за ним не стоит крупная корпорация, ограничивающая полет мысли улучшателей.
А комитет — известное дело, каждый хочет вставить свои 5 копеек и мало на ком висят дедлайны и списки багов.

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

«а зачем?» (к) (тм)

Если между «typedef Widget Object;» и «using Object = Widget;» в плане читабельности разница минимальна, то всякие указатели на функции, ссылки на массивы и прочие сложные типы с юзингом читаются однозначно проще.

Плюс, using можно использовать с шаблонами, чтобы частично подставить в шаблон некоторые параметры и позволять дальше подставлять остальные — то, чего нельзя добиться с тайпдефами.

Плюс, using можно использовать с шаблонами,

Плюс появилась еще одна возможность выедать мозги на интервью, как раньше со static.

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

Про юзинг на интервью я бы не спрашивал.
Да, знать о нём стоит, конечно, — но если человек не знает, это ничего плохого о нём не говорит. Ибо разобраться с этим можно за пять минут.

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

Опыт показывает, что такие ярмарки тщеславия в 90% случаев случаются на С++ интервью.

Мой опыт показывает обратное. Со мной ни разу «ярмарки тщеславия» на интервью не случалось.
Хотя тут не стану спорить, я всего был на 4 или 5.

Можно провести параллель со старым
typedef bool(*PredicatePtr)(const Widget&);

и новым

using PredicatePtr = bool(*)(const Widget&);

и нельзя )) потому что «новым» это вотЪ ))

using PredicatePtr = auto (*) (const Widget&) -> bool;

А вообще «си++ правильно» это вотЪ ))

using PredicateFunc = auto (const C1&) -> bool;
using PredicatePtr = PredicateFunc * ;

ЗЫ: и вообще указатель раз уж вы «сырые указатели на функции» используете писать прямо по месту инстанциации ))

и нельзя )) потому что «новым» это вотЪ ))
using PredicatePtr = auto (*) (const Widget&) -> bool;

Мой вариант тоже «новый», по сравнению с тайпдефом. И я выбрал его не из-за «новизны», если что.

А если вы считаете, что «auto (*) (const Widget&) -> bool» читабельнее, и ваши коллеги с этим согласны — пожалуйста, пишите так. Я с этим не согласен, для меня оптимальный вариант «using PredicatePtr = bool(*)(const Widget&)».

А вообще «си++ правильно» это вотЪ ))

Кто сказал, что это правильно? Очередная вкусовщина.
Так тоже можно, если нужно. Но я пока не вижу, где может понадобиться два отдельных типа для функции и указателя на неё. Обычно на практике в 99% случаев приходится работать именно с указателями.

ЗЫ: и вообще указатель раз уж вы «сырые указатели на функции» используете писать прямо по месту инстанциации ))

Можно и так. А можно и объявить тип Ptr и передавать сразу его. Опять же, вопрос стиля.

Кто сказал, что это правильно?

потому что разделение тот самый solid

Очередная вкусовщина.

чудак человек ты же ж раз за разом подтверждает безвкусицу и что никакой надобности в «новом» у тебя на самом деле нет и ты «никогда не было и вот опять» «покрываешь» «это «вкусовщиной» ))

Обычно на практике в 99% случаев приходится работать именно с указателями.

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

Опять же, вопрос стиля.

Лёлик ты не понимаешь об чём я ))

потому что разделение тот самый solid

SOLID тоже нужно использовать с умом. И в случае с этим конкретным примером он неуместен.
Если бы кому-то в другом месте был нужен тип самой функции, без указателя, — я бы мог согласиться. Но на моей практике такого пока не встречалось. Разве что в каком-то библиотечном шаблонном коде, но там обычно вся эта чехарда из юзингов/тайпдефов носила более локальный характер и наружу не выставлялась.

чудак человек ты же ж раз за разом подтверждает безвкусицу и что никакой надобности в «новом» у тебя на самом деле нет и ты «никогда не было и вот опять» «покрываешь» «это «вкусовщиной» ))

Это ты чудак человек, что продолжаешь упорно выставлять своё мнение за единственное правильное, называть всё, что тебе лично не нравится, «безвкусицей», и пропускать мимо ушей все мои аргументы (раз пишешь, что «никакой надобности в „новом“ у тебя на самом деле нет»).

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

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

Для тебя архаизм — не работай. Для меня указатели на функции пока что не архаизм. Это не то же самое, что какие-нибудь указатели на динамически выделенные объекты, не завёрнутые в unique или shared поинтеры.

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

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

auto t = static_cast<some_type>(something);

Просто, чего уж тут.

Знаете чем ещё аргументируют? Тем, что оно хорошо выравнивается.... ну когда все авто...

Изменений много по сравнению с++14, хотя и меньше по сравнению с c++11.
— auto_ptr удалён наконец-то;
— ключ. слово register удалено;
— удалён operator++(bool);
— удалён deprecated exception (это когда пишем ’void fooThrowsInt(int a) throw(int) { ... }’);
— bind1st()/bind2nd()/mem_fun() удалены, потому что можем использовать лямбды;
— триграфы (trigraphs) удалены;
— поддержка guaranteed copy elision (но употребив флаг -fno-elide-constructors можем увидеть разницу);
— раньше были lvalue и rvalue, а теперь список стал более полным: lvalue, glvalue, xvalue, rvalue, prvalue;
— dynamic memory allocation for over-aligned data;
— exception specifications as part of the type system;
— structured binding declarations (можем писать ’auto [iter, inserted] = mySet.insert(10)’);
— init statement for ’if’ and ’switch’;
— inline variables;
— constexpr lambda expressions;
— nested namespaces!;
— fold expressions;
— if constexpr;
— template code simplification;
— declaring non-type template parameters with ’auto’;
— string_view
— filesystem (наконец-то только ради неё не надо тянуть boost как зависимость);
....
И это далеко не полный список, и я к тому, что новшеств всё равно много. Так что однозначно стоит того, чтобы начинать смело применять в новых проектах и даже пробовать рефакать старые =)
Structured binding, string_view и filesystem я уже применяю относительно давно.

structured binding declarations (можем писать ’auto [iter, inserted] = mySet.insert(10)’);

выкусите, goвнокодеры!

ключ. слово register удалено

ждем, когда уже указатели удалят :)

Насчет register — у меня тоже первая ассциация была, «а какого х?!»
Насколько я помню, это по-любому чисто рекомендательная инструкция компилеру, так что его ее трогать-то было?

А что бы не смущать неокрепшие умы программистов всякими «рекомендательными» директивами. inline не удалили случайно?

Без него пока в определенной ситуации не обойтись. Он же не только про инлайн говорит, но и про многое другое (правильную терминологию уже забыл).

Эм.. да ладно. Про что ещё кроме инлайна может говорить инлайн? Я про старые-добрые инлайн функции, там выше что-то написали про

inline variables

что это такое я еще не в курсе.

что это такое я еще не в курсе.

Це про можливість заінлайнити статік мембер класу прямо в хедер-файлі і не отримати помилку лінковки про редефінішн змінної

— dynamic memory allocation for over-aligned data;
— structured binding declarations

Вот за это спасибо стандартизаторам.

Включая режим зануды... :)

— bind1st()/bind2nd()/mem_fun() удалены, потому что можем использовать лямбды;

Не совсем поэтому.
Просто bind1st/2nd требуют от функтора иметь вложенные тайпдефы: first/second_argument_type. Которые определять ручками (или наследоваться от ныне также задепрекейченных std::unary/binary_function) тупо влом (а в лямбдах так и вовсе невозможно), да и это лишнее в современном языке.
На смену этому всему зоопарку ещё в 11 стандарте пришёл std::bind. Ну и те же лямбды, конечно. Тут уже по ситуации, кому что удобнее.

Поэтому старьё сначала задепрекейтили, а теперь, вот, наконец удалили. Как и в случае с std::auto_ptr.

Ну а std::mem_fun стал ненужным по той же причине, по которой и std::mem_fun_ref: с 11 стандарта появился более современный std::mem_fn. Он умеет работать и с указателями на объект, и со ссылками.
А два старых шаблона также были задепрекейчены ещё в C++11, и теперь спустя 6 лет их удаляют.

— раньше были lvalue и rvalue, а теперь список стал более полным: lvalue, glvalue, xvalue, rvalue, prvalue;

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

На практике важно понимать только две (три) категории: lvalue, rvalue (prvalue, xvalue).
Последние две являются подвидами rvalue:

foo(Widget()); // prvalue

Widget w; foo(std::move(w)); // xvalue

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

Для реальных проектов есть Rust, а с С++ сейчас слишком много рисков.

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

У нас не так много go разрабов, которые умеют в кодогенерацию, zero-alloc и в offheap.
Даже TDD является непосильной ношей, не смотря на то что golang почти что лучший язык в этом плане.

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

И как много сейчас таких «реальных» проектов?

Ну, например, все Serverless Related сервисы Амазона и их Kinesis. После развала Windriver тоже много около-DPDKшных проектов у Sony, SKT Telecom и NTT Docomo, Broadcom тоже на rust’e SDNы пишет... Просто у вас реальность немного отличается, или у меня.

В моей реальности rust-программистов днем с огнем не сыщешь. Да и с переводом плюсовых проектов на rust есть некоторые технические проблемы, ибо rust не является надстройкой над С++.

Насколько я знаю, rust вообще задумывался как язык системного программирования, и эдакий «убийца С». Но если верить вашим словам, используют его преимущественно в нише С++.

rust вообще задумывался как язык системного программирования, и эдакий «убийца С»

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

В rust’e решён вопрос потокобезопасности и есть довольно много проверок, которые в случае с C++ просто невозможны.

Borrowing Check со смарт поинтером сравнивать нельзя.

да, только это все небесплатно

Не думаю что мне стоит объяснять что делает LLVM-ный фронтенд Rust’a и чем это отличается от CLang’a.

Ну я больше 10ти лет занимаюсь разработкой компиляторов... наверное я что-то знаю %)

На самом деле большая часть проверок и типобезопасности уежает на этап компиляции, overhead’a в рантайме у Rust’a нету... разве что Pluggable Arena Allocator при линковке (раньше вообще был jemalloc), но сейчас и его поправили.

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

У нас в основном не решают вопрос накопления/обмена опытом, а Rust разрабов надо не искать, а обучать... по этому так то оно в Украине и получается, что даже продуктовые компании ищут «суперменов», которые уже давно эвакуировались.

В моей реальности rust-программистов днем с огнем не сыщешь.

в моїй реальності я в стоплисті ГЛа, так що куй ти мене знайдеш

Більшість нових проектів на С++17. Старі проекти переведені на С++11.

У старих лінуксах (наприклад ubuntu 14 04), немає компілятора та ліб, ні з коробки, ні з реп, якіб могли підтримувати 17 плюси, тому важко перейти на 17 коли є підтримка таких доісторичних ОС

А что такого есть в 17-м, что может мотивировать к немедленному переходу ?

Різні покращення і нові фічі, які дозволяють писати/читати код швидше. Само собою і над перформансом попрацювали.

Думаю кожен знайде, щось цікаве для себе.
stackoverflow.com/...​e-the-new-features-in-c17

Уже 2019(без 5 хвилин) рік, що за поняття таке «Немедленный переход»?

Як показує практика, треба не мало часу аби спочатку, банально, роздуплитись що та нова фіча робить, а по-друге, витратити ще більше часу аби зрозуміти як саме її ефективно використовувати, а не фічі заради фіч. Тому перший час це точно не буде збільшення

писати/читати код швидше.

Само собою на це треба час. Я про це написав трохи нижче, що є така складова як конкурентоспроможність на ринку.

Конкурентоспособность это time-to-market и отсутствие багов. Каким способом это будет достигнуто — рынок не волнует. Хоть на турбо паскале пишите.

А хто буде мейнтейнити той турбо паскаль коли ви захочете покинути проект або підете у відпустку на місяць?
Якщо говорити про «середню» компанію, то у них є стек технологій (можливо не описаний явно, але він є) і від нього і пляшуть.

Ну от є наприклад компанія закордоном яка пише свій продукт і в якийсь час головний архітектор вирішує, що пора переходити на новий стандарт (побачив він там профіти для проекту і команди — наприклад зможуть відмовитись від частини сторонніх бібліотек). І от вони пишуть ще деякий час проект на цьому стандарті і вирішують передати продукт на аутсорс/аутстафф для оптимізації витрат. Відкривають вакансії в Україні і шукають людей і тут уже ніхто не задається запитаннями, а в чому профіт використання, вас просто ставлять перед фактом, що є такий стек технологій і чим менше ви підходите під цей стек тим менше у вас шансів на вдачу з цим проектом.

і в якийсь час головний архітектор вирішує, що пора переходити на новий стандарт

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

Я розумію, що більша частина проектів які потрапляють в Україну це копроліти які треба мейнтейнити, але повірте мені, що є безліч проектів які стартують з нуля і стек технологій там аж зовсім не коболи, турбо паскалі :D

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

копроліти

и

мейнтейнити

, это тоже новый «стандарт»?

абсолютно вірно, це нові ключові слова :)
Власне, мені ця дискусія не цікава, тому що у кожного свій суб"єктивний досвід (хтось сидить на проекті овер 10 років і там все статично і ніяких нових віянь, хтось інший змінює проекти раз в декілька років і від проекта до проекта зтикається з різними підходами до вибору технологій і їх використання).

Мене цікавить реальний стан на ринку. Ви відповіли, що у вас на проекті вистачає 11 стандарту — відповідь прийнята, дякую.

Ещё и как будут, если нет серьёзных причин задерживаться на старых. Ибо на новых меинтейнить такой проект гораздо удобнее. Улучшается качество кода — как следствие, ускоряется процесс разработки новых фич и багфикса. Бизнесу это тоже выгодно.
А когда код тонет в легаси, которое не апгрейдят из-за чьего-то консерватизма... Ну, это печалька. Я б на таком проекте не задерживался.

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

И не стоит сравнивать Кобол с плюсами, стандарты которых просто расширяют и дополняют язык, ломая обратную совместимость только в очень редких случаях. Позаменять везде по коду std::auto_ptr на std::unique_ptr, или выкосить спецификатор register — задача несложная даже для больших проектов. И это не то же самое, что переписывать проект с нуля, переводя его с Кобола на какой-нибудь Go или Rust.

И не стоит сравнивать Кобол с плюсами,

Другой пример — несколько лет назад на фрилансе для одного БМВ офиса делал клиент/сервер для ТЛС. Так вот требование заказчика было — Визуал Студия 6. Убедить заказчика перейти на 12 студию не удалось, их проект, где должен был работать этот клиент/сервер, разработан на 6 студии.

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

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

Из-за тысячи причин, начиная от предустановленных ОС на пользовательских машинах, кончая совместимостью с 3rd party библиотеками и компонентами.

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

Я уже задавал этот вопрос: какой процент кодобазы требует немедленного внедрения нового стандарта? Что-то мне подсказывает, что проблемой в ней будет отсутствие комментариев и рисковые приведения типов, а не присутствие autoptr. Отдельный большой вопрос, чем поможет усовершенствования типа sed ’s/boost/std/g’ ?

НЕМЕДЛЕННОГО — никакой, очевидно же.
Это просто приятности для программистов, позволяющие уменьшить количество лишнего рутинного кода и сосредоточиться на главном. Что, в свою очередь, помогает быстрее пилить фичи и допускать меньше багов при этом.

уменьшить количество лишнего рутинного кода и сосредоточиться на главном.

По-моему именно постоянная чехарда стандартов отвлекает от решения собсно задачи.

Что, в свою очередь, помогает быстрее пилить фичи и допускать меньше багов при этом.

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

По-моему именно постоянная чехарда стандартов отвлекает от решения собсно задачи.

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

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

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

А хто буде мейнтейнити той турбо паскаль коли ви захочете покинути проект або підете у відпустку на місяць?

А кто будет мейнтейнить продукт любителя новых фич?

«А кто будет наблюдать за наблюдателями?»
До чого тут любителі нових фіч? Є об"єктивна реальність, що кожних 3 роки випускають новий стандарт C++ (принаймні поки що тенденція така). Рано чи пізно ці стандарти будуть використовуватись в проектах і потім уже буде стояти питання чи хочу і можу я читати і писати такий код.

До чого тут любителі нових фіч?

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

Рано чи пізно ці стандарти будуть використовуватись в проектах і потім уже буде стояти питання чи хочу і можу я читати і писати такий код.

Что-то концы с концами не сводятся, вначале объявить использование нового стандарта, а потом искать тех, кто будет читать и писать на нём код?

Емм, а що тут не сходиться?
1. Люди звільняються
2. Проекти ростуть
3. Проекти переїжджають на аутсорс
4. Стартують нові проекти з заданими вимогами від замовника

Уже писав про це. Мені не цікаво чому ті чи інші проекти пишуться на тих чи інших стандартах, а цікавить хто уже використовує найновіший.

Все інше це теми холіварів з суб«єктивними доводами типу «это другие не влезут, а мой влезет!»

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

Вообще не сродни. Новые стандарты на то и новые, что они актуальны сейчас, либо станут актуальными через пару-тройку лет. Поэтому с ними люди постепенно ознакамливаются (если они уже не погрузились в слишком специфическую область, где им эти знания точно не пригодятся) и искать таких людей будет куда проще.
Тем более, что ничего такого переворачивающего язык с ног на голову в C++17 нет — всего лишь надстройка над старым стандартом, добавляющая немного удобства в процесс написания кода. Поэтому разобраться с 17-ым стандартом человеку, который уже знаком с 11/14, не составит особого труда. В отличие от изучения какого-то устаревшего языка.

Є об"єктивна реальність, що кожних 3 роки випускають новий стандарт C++

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

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

через 3 года это будут уже старые фичи.

через 3 года весь код на си++ превращается в турбо паскаль ))

ЗЫ: и передаётся на поддержку в Индию #lol ))

это можно сказать про любой язык программирования. некоторые винят в этом чрезмерное увлечение ООП, паттернами, SOLID, бесконечную декомпозицию, другие же считают что виноват во всем скрам/аджаил/канбан/леан или даже не следование всему вышеперечисленному. истина конечно же где-то посередине, но С++ точно не виноват.

но С++ точно не виноват.

золотые слова
плюсы это инструмент
грабли не виноваты, что ктото в детсве на них наступил

написанном на самом свежем стандарте си++ ))

грабли не виноваты, что ктото в детсве на них наступил

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

вас просто ставлять перед фактом, що є такий стек технологій і чим менше ви підходите під цей стек тим менше у вас шансів на вдачу з цим проектом.

=>

А хто буде мейнтейнити той турбо паскаль

Де паскаль і де плюси? Wake up Neo, you obosralsa!

Ваша думка дуже важлива для нас, залишайтесь на лінії.. ту ту тууууу......

У випадку з програмуванням на плюсах, володіння конкретним стандартом це не перевага, а просто опція і стрічка в резюме.
Як на мене, хорошого С++ програміста від поганого відрізняє геть не знання конкретної синтаксичної конструкції з конкретного 1х стандарту.
Єдине, що справді може бути недоліком, це якщо людина дофіга років писала на 98-03 стандарту, а проект на 11+ і вона принципово не хоче або не може опанувати нове, тоді біда.
У випадку, ж, коли середньостатистичний с++ девелопер писав проект на 11 стандарті, а його кличуть на проект де є 17, то цей перехід відбудеться легко і займе мінімум часу.

Переход на новый стандарт это всегда риск несовместимости.
Какие преимущества он дает, чтобы идти на эти риски?
Какой процент кодобазы будет эти новые фичи включать?

Це питання до тих людей, які будуть запроваджувати нові стандарти (архітектор/клієнт/ПМ/...).

От приходите ви на проект, а там все написано на XX стандарті і це на вигляд уже не C++, а китайська грамота яку і прочитати ледве можна, а клієнт/тл хоче, щоб ви викотили фікс чи імпрувмент за короткий термін.

Я завів цю тему не для того, щоб просувати C++17 (я й сам можна сказати не знаю його), а для того, щоб вияснити чи є уже компанії які використовують цей стандарт

От приходите ви на проект, а там все написано на XX стандарті і це на вигляд уже не C++, а китайська грамота яку і прочитати ледве можна, а клієнт/тл хоче, щоб ви викотили фікс чи імпрувмент за короткий термін.

Уже успели наговнять, внедрить и отдать на саппорт в третий мир?

Успєлі і ви нажаль не встигли прийняти участь. Чекаємо вас наступного року

Спасибо, но тэг С++хх хороший резон не участвовать в проекте.

в 17м, ровно 100 лет назад победила воср. так что сам владимир иллич велел. прямо из мавзолея

Поки пишемо на 14-му стандарті, в планах 17-й, але вже, напевне, з нового року.

а что именно с 17-го чего нет в 14-м «в планах»? )) причём такого что вот прямо горит!!! )))

Та в принципі все є, хіба пару разів стикався з тим, що треба був функціонал атрибуту [[nodiscard]]

Коли правда, что

мотивація мені їх зрозуміла

, так и ответ должен быть зрозуміл. Плюсы будут жить и здравствовать еще долго после того как многих состарившихся формошлепов выставят с галер на мороз, но нужно признать, что уже сейчас плюсы не мейнстрим (даже в высоконагруженных проектах все неоднозначно — ну тот же hadoop на Яве написан).
А потому основная тема — не развитие новых проектов, а поддержка существующих. И тот же мой любимый QuantLib еще долго будет тянуть обратную совместимость с 98, ибо «one auto and you cannot compile it with legacy VS versions that are still used by the banks».

Справа в тому, щоб залишатись конкурентноспроможним на ринку. Зараз зустрічаються люди які досі на практиці чи в теорії не стикались з C++11.

Це ні в якому разі не проблема глобального масштабу, але на мою думку, якщо на проекті використовуються нові стандарти, то і на співбесідах перевага надається людям, які знають ці стандарти.

Так, всі ми розуміємо, що не проблема підтягнути свої знання коли треба буде, але якщо систематично не робити цього, то прірва може виявитись достатньо великою, яку непросто покрити за одну ніч і потім в продакшн коді ловити лулзи типу 5 вложених лямбд які захоплюють this і це все передається як колбек в сторонню бібліотеку. Ну або невикористання або неправильне використання smart pointers чи locker’ів для мютексів.

Ты (правильно) рассуждаешь с колокольни дева. А у фирм — особенно больших — свои IT полиси. Что версии C++, я сам видел, как с Window XP не переходили, хотя Microsoft официально закончила выпускать для нее патчи. Почему такое сплошь и рядом — отдельная большая тема. Факт что-таки да, девы часто меняют работу из-за того что не хотят сидеть на устаревших технологиях. Но девы — не единственный фактор для фирм.

але якщо систематично не робити цього, то прірва може виявитись достатньо великою, яку непросто покрити за одну ніч і потім в продакшн коді ловити лулзи типу 5 вложених лямбд які захоплюють this і це все передається як колбек в сторонню бібліотеку.

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

О, коль уж пошла такая пьянка, то переход на новую версию PHP (даже не в смысле языка разработки, а в смысле интерпретатора на сервере) — это тоже нюанz.
Если кому надо — в конце статьи мелким шрифтом как это сделать безболезненно :)
letyourmoneygrow.com/...​ubuntu-18-04-1-lts-linux

А з ангулярщиками як справи наразі? Проконтролюйте, щоб всі вони починали нові книги по пхп читати, щоб потім на плюси свічнутись

КОБОЛ, говорят тоже еще пользуется спросом :)

ніт. )) но пользуются спросом программисты на кобол ))

И тот же мой любимый QuantLib еще долго будет тянуть обратную совместимость с 98, ибо «one auto and you cannot compile it with legacy VS versions that are still used by the banks»

А под какую систему компилится этот код под стандарт C++98, под DOS или Win95?

Под процессор Zilog Z80 (слыхал про такой)?
А если серьезно, то:
1. Операционная система и стандарт C++ — это почти ортогональные вещи («почти», потому что под старые системы новые компилеры обычно не выпускают)
2. В банках до сих пор много чего на мейнфреймах, а потому доходит и до того, что (подмножество) STL приходится имплементировать самому (я тоже в этом участвовал — заменял примитивный quicksort, переполнявший стек, на heapsort).

«почти», потому что под старые системы новые компилеры обычно не выпускают

Вообще да, мороки может оказаться больше, чем кажется. Дело в том, что под новую студию можно откомпилить минимум под NT4 и Win2K, значит надо ставить старую среду, чтоб писать там код. А она нормально станет только на старую систему. А старую систему можно поставить нормально только на старое железо. Либо всё это установить на виртуальную машину, и работать в ней.

(даже в высоконагруженных проектах все неоднозначно — ну тот же hadoop на Яве написан).

ну да а сам JVM уже на «плюсах» да и операционки в которых всё это вертится принннём )) так что круг замкнулся.

Ну и много ли людей пишут операционки? (ок, Linux developer comminity действительно большое, ну да за это деньги [непосредственно] не платят, да и там по большей части «без плюсов», не?).
Да, а ведь есть еще Go (о нем я лично, правда, знаю только что он есть, и что docker на нем написан).

Так или иначе, факт, что времена, когда все высокопроизводительное писали на «плюсах» (если только не лезли сразу в asm :)) давно прошли.
А уж времена, когда на нем было обычно писать и, скажем, GUI — и подавно прошли (не, я в курсе про Qt, но это не мейнстрим).

Ну и много ли людей пишут операционки?

х.з. )) полагаю сравнимо числом с числом людями которые пишут hadoop на яве ))

и, скажем, GUI

х.з. смотря что считать «gui» у того же ж qt есть qml

х.з. )) полагаю сравнимо числом с числом людями которые пишут hadoop на яве ))

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

когда все высокопроизводительное

а кстати да сам hadoop это «высокопроизводительное» или это за другое?

Ну это смотря с какого боку. Пробовал я на нем Монте-Карлу — yetanotherquant.com/hadoop — в пересчете на processor core и потребляемую энергию — ну и тормозной, я б сказал. Особенно если сравнивать с решением той же задачи на GPU: papers.ssrn.com/...​s.cfm?abstract_id=2259133
Вот только с КУДой уже я как разработчик был если не тормозным, то уж точно не высокопроизводительным — пока ее изучил, пока написал код.
В ретроспективе я бы, наверное, арендовал бы клауд с хадупом, где подешевле выпросил бы у клауд-провайдера спонсорство как выпросил TESLA K20 у NVIDIA Academy Partnership — и мэп-редюсил бы, не мудрствуя лукаво.

C++11, хоча в нас є деякі штуки імплементовані із С++17 в наших власних бібліотеках. Той самий optional, expected

був недавно на С++ конференції, десь від чверті до третини аудиторії підняло руки коли спитали хто С++17 використовує в реальному продакшені. Приблизно стільки ж склыки досі С++98/03.

Дякую, цікава статистика.
Конференція була в Україні чи за кордоном? Цікавить контингент конференції

Той самий optional

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

десь від чверті до третини аудиторії підняло руки коли спитали хто С++17 використовує в реальному продакшені.

а провели уже более конкретный опрос а что уже более конкретно что конкретно есть в 17-м и без этого ну никак? ))

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

А що можна під C++98 можна підключити STL з std::optional? Розкажіть як, дійсно цікаво!

а провели уже более конкретный опрос а что уже более конкретно что конкретно есть в 17-м и без этого ну никак? ))

Я здогадуюсь, що ви використовуєте компілятор із підтримкою С++11 в своїй повсякденній роботі. І от у мене зустрічне питання: а що було такого в C++11, що вам не вистачало в старому доброму C++98? Або навіть для чого взагалі той C++ був же ж C і нормально жили, а перед цим ассемблер і взагалі було круто, не було світчерів і тільки тру кодери писали свій тру код
mov ah,40h int 21h

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

У самого си уже тоже несколько стандартов и что же ж теперь делать? Дело ведь не в стандарте дело в хомячковом пиетете к.

Мова програмування — це інструмент за допомогою якого можна отримати бажаний результат за прийнятний час і з прийнятними зусиллями. Якщо припустити, що мова C++ це швейцарський ніж, то кожен із стандартів додає нові функціональні можливості в цей мультитул і заодно робить деякі покращення в старих компонентах (дизайн покращено, що зменшує вірогідність порізатись при витягуванні з інструментів).

Ніхто вас не заставляє забивати цвяхи молотком, можете це робити це каменем і бути впевненим, що є лише дві думки: ваша і неправильна

Мова програмування — це інструмент за допомогою

ніт.

мова C++ це швейцарський ніж,

швейцарский нож — интересная забавка, но не в коем разе, не промышленный инструмент.

Настоящий швейцарский армейский нож, то есть нож, выпущеный по заказу швейцарской армии, и который должен быть у каждого резервиста в Швейцарии — весьма функциональный инструмент. Я пробовал мод. 1961 (обр. 1978), остался весьма впечатленным.

Главное что там хороший набор открывашек для пива и консерв и сталь приличная. Мне в походах уже долго служит и за лет 10 только 1-2 раз подтачивал чуть.
Но вот гайку ты им не открутишь.

Я Лезерманом пользуюсь вот уже пять лет. Ни разу еще не подтачивал. В походе незаменимая вещь. Покупали мне в Штатах

У меня уже больше 10 лет, так что уже пришлось подтачивать чуть. По сути доводку сделал на двух брусках ручками, ну и на деревянном бруске по окончании.

Не открутишь. Но он и не для этого.

швейцарский нож — интересная забавка, но не в коем разе, не промышленный инструмент.
: а що було такого в C++11, що вам не вистачало в старому доброму C++98

мув семантика, хроно із наносекундами...

мув семантика

старые добрые поинтеры рулят

не достаточно хорошо, значить, рулили

в си++ было недостаточно джавы ))

ооп зло

у джавы даже смарт поинтеров нет. сплошной гарбейдж

всё есть у джавы есть JNI ))

я ж и говорю

сплошной гарбейдж

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

Не рулят

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

А потом код из дикой кучи free, причем пару случаев из всего комбинаторного стада забывают и потекли.
Но веселее, когда free дважды на одно выделение натравливают, причем это возникает редко. Или натравливают на случайный указатель.

и потекли

валгринд рулит

Не рулит. Он все одно все утечки не найдет, тупой-с.

а что не найдет — то значит в жизни не происходит

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

Интересно, а что означает эта буковка С в этой самой СТЛ, которая не вопрос стандарта?

а провели уже более конкретный опрос а что уже более конкретно что конкретно есть в 17-м и без этого ну никак? ))

Вот конкретно мне понравилась идея того же самого expected но в 17 он таки часть библиотеки, а вот в 20 к нему обещают синтакс шугер. А так я живу в 11 ну почти в 14, про 17 и прочие только начинаю почитывать.

Интересно, а что означает эта буковка С в этой самой СТЛ, которая не вопрос стандарта?

Stepanovʼs template library.

Это вы мне таки из какого года пишите то?

Как-то, будучи неопытным джуном, которого интересовал этот вопрос, поднял на доу срач на эту тему. Было весело :)
Вообще да, библиотека как бы называется «стандартной», но она не стандартная. Большую её часть (не всю) в 98 году стандартизировали, но в стандарте плюсов никаких упоминаний «STL» нет. Хотя многие продолжают называть «STL» именно стандартизированную часть «стандартной» библиотеки Степанова: std’шные контейнеры, итераторы, алгоритмы и функторы. Как-то так.

Проекты на WinRt требуют C++ 17

std::optional не хватает)

Згоден. В свій час написав свою версію)

В свій час написав свою версію)

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

Я так понимаю весь пиетет «новый стандарт!» (к) (тм) от глубокого недостатка знаний и вообще. Что само по себе совершенно не ново.

Звідки у вас впевненість, що в усіх проектах направо і наліво використовується буст? В бусті і логгер свій є давним давно, але чомусь на кожному проекті всі пишуть свої логгери.
А ще час від часу люди пишуть свої аллокатори і контейнери в залежності від потреб проекту (пишеться це все з голови чи з підглядуванням в чийсь код — це уже інше питання).

и свой стандарт си++ ))

Удобно же когда такие мелочи есть из коробки.

Пока хватает С++11

Подписаться на комментарии