_>На мой взгляд это самая большая проблема C++, которую следовало бы решать в первую очередь, вместо всяких ненужных модулей и т.п.
самая большая проблема C++ это просто феерически непомерная сложность языка и "culture of complexity" у коммьюнити, когда "не написал шаблонный код" == неосилятор языка. В то время как должно быть "написал шаблонный код" == автор гей по дефолту, пока сильно не обосновал обратное.
Здравствуйте, alex_public, Вы писали:
_>Полностью согласен. На мой взгляд это самая большая проблема C++, которую следовало бы решать в первую очередь, вместо всяких ненужных модулей и т.п. А они вместо этого отложили статическую интроспекцию не раньше C++23...
Интересно, как она могла бы работать, эта самая интроспекция в C++. Ну вот допустим, выясню я, что некое поле в структуре имеет тип std::string, а он, по природе своей — тоже некая структура с загадочными полями. Ну и дальше-то что, как мне его в строку-то превратить?
Ну т.е., к примеру, про std::string я, положим, могу и знать. А если там какая-нибудь Qt'ная строка, и еще какая-нибудь самодельная?
Здравствуйте, Pzz, Вы писали:
AN>>Шаблоны в 90-х появились. Но злоупотребление метапрограммированием и раньше было, только вместо шаблонов использовались макросы с параметрами.
Pzz>Макросы с параметрами сроду не были тьюринг-полнымы, так что на них было особо не развернуться.
Здравствуйте, Pzz, Вы писали:
IID>>Ну что вы, конечно не проверяйте. IID>>Активных (непофикшенных) крешей, с авто воспроизведением, найденных syzcaller'ом, всего то 3000 (три тысячи) штук. Среднее время фикса полгода.
Pzz>Вопрос про эффективность ведь не я поднял. Pzz>Тут кто-то рассказал, что в C++ достигается недостижимое:
Почему не достижимое? Вполне достижимое
Pzz>совмещается типа-безопасность языков высокого уровня с эффективностью кода, практически как в Си. Вот я и поинтересовался.
Да. За счет выноса множества проверок на этап компиляции.
Еще constexpr допилят, и кучу вычислений также можно будет вынести на этап компиляции
Здравствуйте, Marty, Вы писали:
_>>Ну да, это того же типа продукт. Кстати, а он с st-link работает? M>Честно говоря, я его не трогал. Его трогали коллеги, которые моторами крутят. Они вроде как через UART его использовали
Ещё один повод перейти на jlink. ) Кстати, а STMStudio естественно работает напрямую с st-link, правда при этом полностью его захватывает в своё пользование.
_>>Ну для начала он банально намного быстрее. Т.е. понятно что это вообще не принципиальный параметр, но всё равно как сильно приятнее с ним. Ну и потом там есть множество мелких удобство. Одно из которых как раз "свой printf" (причём поделённый на каналы и в отдельном удобном приложение). M>Хм. А как эти printf'ы будут шарить SWD с отладчиком?
Так оно через отладчик и работает https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/. ) Т.е. через забор значение в фиксированной области памяти. В принципе такое и самому руками можно сделать, но удобнее когда оно уже встроено в отладчик и имеет удобный интерфейс. Ну и опять же данная конкретная реализация имеет производительность намного лучше swo и семихостинга.
Здравствуйте, Pzz, Вы писали:
_>>Насчёт тормозов всё верно. Только ты вот это сейчас описал совсем не "программы на C++, активно использующие всякое там автоматическое освобождение", а скорее программиста на Java/C# севшего за C++. Потому как в обычном C++ приложение мелкие объекты с фиксированным временем жизни традиционно размещаются на стеке, а не в куче. Pzz>Когда ты размещаешь std::string на стеке, буфер-то еёйный все равно размещается в куче.
Нет, не в куче. Ознакомься с такой темой как SSO в C++.
Pzz>Это вообще, с точки зрения эффективности, злобный антипаттерн. Pzz>Программы на C++, активно использующие всякое там автоматическое освобождение, имеют тенденцию создавать в куче объекты с очень коротким временем жизни, и сразу же их освобождать.
А можно примеров, и как бы это было реализовано на сишечке?
Pzz>Это ОЧЕНЬ медленно, медленнее, например, чем автоматическое управление памятью в языках со сборкой мусора, типа какого-нибудь даже яваскрипта.
Здравствуйте, Pzz, Вы писали:
_>>Насчёт тормозов всё верно. Только ты вот это сейчас описал совсем не "программы на C++, активно использующие всякое там автоматическое освобождение", а скорее программиста на Java/C# севшего за C++. Потому как в обычном C++ приложение мелкие объекты с фиксированным временем жизни традиционно размещаются на стеке, а не в куче.
Pzz>Когда ты размещаешь std::string на стеке, буфер-то еёйный все равно размещается в куче.
А говорил, что знаешь C++
Даже если бы во всех известных реализациях не было бы "инлайн" буфера в самом объекте std::string, то без присвоения объекту значения никаких аллокаций не будет. Это раз.
Во вторых, как ты в сишечке без malloca работаешь со строками?
Здравствуйте, Pzz, Вы писали:
_>>Вообще то нет. Но предположим даже что да. И что бы было в этом страшного (если это конечно не программирование под МК, но там и вопросов таких не стоит)? Ведь речь о машинном коде, а не о написанном человеком... Pzz>Кэш инструкций выносится, производительность падает, батарейка быстрее садится...
Кэш как раз страдает в случае виртуальных функций (или просто указателей на функции, в случае языка C), потому как предсказатель плохо работает. А в случае линейного массива (что кода, что данных), всё гарантированно будет в кэше.
Pzz>Ну лямбду, скорее всего, потом позовут, когда чего-нибудь случится или кончится. А в промежутке она будет храниться в виде указателя.
В виде указателя (на языке C++ это std::function) конечно же тоже иногда хранят, но это скорее если требуется менять их в процессе работы приложения или нужен какой-то контейнер таких сущностей.
Здравствуйте, alex_public, Вы писали:
Pzz>>Когда ты размещаешь std::string на стеке, буфер-то еёйный все равно размещается в куче.
_>Нет, не в куче. Ознакомься с такой темой как SSO в C++.
Ну, это очевидная оптимизация, но как-то немного унылая. Много чего во внутренний буфер не влезет, и во всех строках с внешним буфером, внутренний буфер будет просто выброшенной памятью.
Здравствуйте, Marty, Вы писали:
Pzz>>Программы на C++, активно использующие всякое там автоматическое освобождение, имеют тенденцию создавать в куче объекты с очень коротким временем жизни, и сразу же их освобождать.
M>А можно примеров, и как бы это было реализовано на сишечке?
В разных случаях по-разному. Но нет особых причин выбирать, среди прочих возможностей, разведение короткоживущих объектов в куче.
В C++, разумеется, тоже можно сделать по-разному. Но зачем, если завести строку на стеке так удобно?
Pzz>>Это ОЧЕНЬ медленно, медленнее, например, чем автоматическое управление памятью в языках со сборкой мусора, типа какого-нибудь даже яваскрипта.
M>С чего бы это?
Здравствуйте, Marty, Вы писали:
M>Даже если бы во всех известных реализациях не было бы "инлайн" буфера в самом объекте std::string, то без присвоения объекту значения никаких аллокаций не будет. Это раз.
Что вы так все любите пример с присваиванием? У вас в программах, что ли, сплошные присванивания, и никаких прочих действий?
M>Во вторых, как ты в сишечке без malloca работаешь со строками?
Здравствуйте, alex_public, Вы писали:
_>Кэш как раз страдает в случае виртуальных функций (или просто указателей на функции, в случае языка C), потому как предсказатель плохо работает. А в случае линейного массива (что кода, что данных), всё гарантированно будет в кэше.
Этот кэш, он маленьний. Даже на пентиуме маленький, а на арме совсем маленький.
Ошибка предсказателя всего лишь отправляет в /dev/null результат нескольких спекулятивно вычисленных инструкций, а промах кэша вызывает обращение к памяти, а она медленная, зараза.
Здравствуйте, Pzz, Вы писали:
M>>А можно примеров, и как бы это было реализовано на сишечке?
Pzz>В разных случаях по-разному. Но нет особых причин выбирать, среди прочих возможностей, разведение короткоживущих объектов в куче.
А можно не юлить, а с конкретикой?
Pzz>В C++, разумеется, тоже можно сделать по-разному. Но зачем, если завести строку на стеке так удобно?
На стеке — действительно удобно, и весьма часто на стеке всё и остается, никто в кучу не лазает.
Ты что-то заранее начал оптимизировать, когда это абсолютно не требуется. Но, если уже тебе захотелось оптимизации, используй контейнеры из нового стандарта, которые позволяют задавать объектам экземпляры объектов аллокаторов. Делов-то на 10 минут — написать аллокатор, который выделяет один кусок в куче, потом раздает всем нуждающимся память из него, а потом, когда всё отработало, грохает весь кусок сразу
Pzz>>>Это ОЧЕНЬ медленно, медленнее, например, чем автоматическое управление памятью в языках со сборкой мусора, типа какого-нибудь даже яваскрипта.
M>>С чего бы это?
Pzz>Не знаю. Но правда очень медленно.
Ну, может быть из-за того, что в языках со сборщиком мусора в тот момент ничего не освобождается, а откладывается на неопределенный момент? Это намного лучше?
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, lpd, Вы писали:
_>Т.е. если просто перекомпилировать код с C++98 на C++11, то он может стать гораздо эффективнее. Однако это увеличение гораздо менее важно, чем то, что принесла семантика перемещения в архитектурном плане.
Все-таки "гораздо эффективнее" это уменьшение отклика на 1%? а то и на 0.5%.
Насчет архитектурной роли перемещения ок. Я вообщем не спорю что это фича в теории интересная, но реальная польза только в искуственных hello-wordах.
_>Ха, так причём тут unique_ptr и подсчёт ссылок? Последнее — это shared_ptr и у него естественно нет никаких вопросов с копированием. А в unique_ptr никаких подсчётов ссылок нет.
Я это знаю.
_>Ну ОК, давай напиши сущность с функциональностью unique_ptr, используя любые возможности C++98 (собственно можно хоть C++20 взять без семантики перемещения и это ничего не изменит).
И зачем мне такая радость как unique_ptr<>? Если не брать "hello world"ы, то в сколько-нибудь сложных программах владение памятью и ресурсами им часто не описывается. Проблемы кодеров не в том чтобы не забыть delete, а чтобы учесть редкие и не протестированные ветки исполнения кода(особенно при ошибках), возможные рейсы. Вот от подсчета ссылок польза бывает, но и для этого удобнее GC в большинстве случаев.
_>Дело не в быстродействие, а в удобстве. На кой нужны все эти интерфейсы и прочая ересь, если при статическом полиморфизме компилятор всё равно всё проверит и даже более строго, чем с виртуальными функциями.
Это уже религиозный вопрос. Через 20 лет все окончательно забудут про С++, но и тогда фанатики будут кучковаться, городить лес из скобочек и разруливать все статически.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, Pzz, Вы писали:
M>>Даже если бы во всех известных реализациях не было бы "инлайн" буфера в самом объекте std::string, то без присвоения объекту значения никаких аллокаций не будет. Это раз.
Pzz>Что вы так все любите пример с присваиванием? У вас в программах, что ли, сплошные присванивания, и никаких прочих действий?
Потому что без присваивания ничего из описанного тобой не произойдет. Остальное тоже используем, и что?
M>>Во вторых, как ты в сишечке без malloca работаешь со строками?
Pzz>По-разному, в зависимости от задачи.
А можно конкретики?
Типа, например:
раз...
два...
три...
Здравствуйте, Pzz, Вы писали:
_>>Полностью согласен. На мой взгляд это самая большая проблема C++, которую следовало бы решать в первую очередь, вместо всяких ненужных модулей и т.п. А они вместо этого отложили статическую интроспекцию не раньше C++23... Pzz>Интересно, как она могла бы работать, эта самая интроспекция в C++. Ну вот допустим, выясню я, что некое поле в структуре имеет тип std::string, а он, по природе своей — тоже некая структура с загадочными полями. Ну и дальше-то что, как мне его в строку-то превратить?
В каком смысле превратить в строку? Интроспекция — это информация о типах. У статических языков она есть в абсолютной полноте на момент компиляции. Вопрос в том, насколько приложение может её использовать (обычно для этого в языке требуется наличие элементов метапрограммирования).
В C++ издавна есть зачаточные элементы статической интроспекции: оператор typeid. Т.е. уже давно мы можем без проблем получить на этапе компиляции информацию о любом типе. Однако для полноценной интроспекции в C++ как минимум нет возможности перечислить все члены класса/структуры. Что не позволяет сделать например универсальный сериализатор для произвольных объектов и ещё множество нужных вещей. Сейчас все эти вещи делают или каждый раз руками или через дикие метапрограммные костыли из Boost'а, которые надо ещё подключать на этапе создания каждого сериализуемого типа.
Полноценную реализацию статической интроспекции можно увидеть в языке D. Там без проблем можно написать например универсальную библиотечную функцию to_json(T t), которой можно передать скажем экземпляр пользовательского тип struct User {string name; int age}; и получить нормальный результат.
Причём с учётом того, что эта функциональность существует в D от его рождение (т.е. очень давно) и очевидно не ломает ничего в C++, я никак не могу понять почему комитет не "содрал" с D эту важнейшую возможность ещё в C++11. И тянет до сих пор, хотя в процессе выпуска каждого следующего стандарта это очень подробно обсуждается, но каждый раз откладывается до следующего раза.
Pzz>Ну т.е., к примеру, про std::string я, положим, могу и знать. А если там какая-нибудь Qt'ная строка, и еще какая-нибудь самодельная?
Строка Qt, если что, без проблем конвертируется в std::string. Хотя это к теме статической интроспекции никакого отношения не имеет. Это уже банальные рантаймовые дела.