Comments 119
Не сломается. Но с `#define _ gettext` вы не сможете пользоваться нижним подчёркиванием как именем переменной
А как быть если у меня в старом коде используются глобальная переменная_?
То есть при компиляции в С26 нужно будет выполнить рефакторинг, заменив _ другим именем?
А почему 26? Планируют до 26-ого года это разрабатывать?
Вот это разгон!
У вас еще на С++20 почти никто не переполз, а вы там уже 26 запускаете.
Разработчики многих компиляторов не от скуки очень длительное время держат свежие стандарты в состоянии "экспериментальная поддержка". Это даёт возможность накрутить больше оптимизаций, прежде чем будет зафиксирован ABI
Ну а дальше - специфика приложений. Если ABI приложению важен - обновляются когда стандарт перестаёт быть экспериментальным в компиляторе. Иначе можно жить и на bleeding edge
Да я про пользователей.
Пользователи сидят максимум на 17, мало кто использует даже 20.
А у вас уже 26.
У вас неточные данные. Согласно CppDevSurvey-2023-summary уже 30% разработчиков используют фичи C++20, 70% используют фичи из C++17
Возможно вы правы.
У меня несколько иное впечатление, но спорить не стану.
Жаль штатный apple clang очень сильно отстаёт. Там даже std::format и ranges не работают.
Там обычный (ванильный) clang отлично работает. Вот оба:
$ clang --version
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ /opt/homebrew/opt/llvm/bin/clang --version
Homebrew clang version 16.0.4
Target: arm64-apple-darwin22.5.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin
Спасибо, попробую. Потом надо будет уговорить команду перейти на него и раскатить на билд агентах.
Они (начиная с clang-13) умеют кросс-платформенно собирать под macos. Вот такой тулчейн - https://github.com/manticoresoftware/manticoresearch/blob/master/dist/build_dockers/cross/osx.cmake
и к нему sysroot, и (если нужно) подмножество homebrew с нужными либами - и билд-агентом сможет быть любая машина (хоть "малинка").
А насколько представительно это исследование? Не получается ли так,что те, кто сидят в информационном вакууме на древних версиях, слыхом не слыхивали про этот опрос? Т.е. нет ли там эффекта "интернет-опрос показал, что 100% населения пользуются интернетом"?
Всякое конечно может быть. Но в наше время найти IT-специалиста без доступа к интеренету и в информационном вакууме весьма сложно. Число таких специалистов должно быть пренебрежителлно мало и не влиять значительно на результаты опроса
Число таких специалистов должно быть пренебрежителлно мало и не влиять значительно на результаты опроса
Это интересная гипотеза.
Я например о существовании этого опроса узнал из этого треда, хотя имею доступ к интернету последние 25 лет.
Мои коллеги, числом человек в 25, не знают о нем до сих пор (кроме возможно одного), потому что я никому про этот опрос не рассказывал.
Более того, даже если б мы все знали про опрос, возможно 1-2 из нас пошел бы его проходить, не больше.
Так что насчет пренебрежимо мало ... на самом деле неизвестно.
У нас C++20. Корутины очень кстати оказались.
Reflection, я так понимаю, мы не дождёмся? Концепты+Модули+Рефлекшн и можно было бы положить на комитет.
А опциональный garbage collection планируется когда-нибудь?
Thread pool, как в Qt или или лучше?
Thread pool планируется в виде Executors. Уже выверяется текст основной части Executors для включения в стандарт, так что уже очень скоро
А опциональный garbage collection?
Там вроде как будут только базовые абстракции, конкретных реализаций экзекуторов (в том числе тредпула) не будет.
А кто будет абстракции реализовывать?
Треды же и мутексы готовые из коробки, почему с экзекуторами нельзя так же?
Пробежался еще раз по proposal'у (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2300r7.html). Есть scheduler который создает отдельный тред и работает только с ним, но тред пула нет:
> 10. A specific thread pool implementation is omitted, as per LEWG direction.
Пусть это и ломающее обратную совместимость изменение
Хорошо как!
Обожаю ломать обратную совместимость. Все это любят.
люди из комитета не нашли в открытых кодовых базах мест, где код бы сломался
Ну тогда все ок.
Кроме открытых кодовых баз других ведь не существует.
Хорошо, что предупреждаете.
Отличная реклама нового стандарта.
Можно брать не глядя.
Функция уже сломана, она возвращает неправильный ответ на некоторых наборах значений. А то что результат зависит от локалей вообще для многих сюрприз, учитывая что для целых чисел локали не используются
За поддержку обратной совместимости вообще говоря нужно платить. Так что обратную совместимость не всегда стоить реализовывать.
Еще один вопрос.
Возможна ли такая ситуация, когда комитет правит старые стандарты?
Приведу пример: меня заинтересовала тема с RCU.
Но я пишу под 2011 и переходить на новые стандарты не планирую.
Можно ли подправить стандарт 2011 (или 2017 тоже), чтобы добавить в него только RCU?
Скажем, в виде дополнительной библиотеки, совместимой с этой версией?
Такое делается крайне редко, и как правило для багов. Боюсь что с RCU шансы нулевые.
С другой стороны, скорее всего в ближайшее время появится множество реализаций RCU с интерфейсом стандартной библиотеки, можно будет взять стороннюю библиотеку.
У нас одновременно шло внедрение 11-го стандарта, имплементация корутин и части lock-free примитивов. До RCU не дошли, хватило hazard pointers. И то, что какие-то вещи позже появились в стандарте - ну, писать стало проще и компактнее. А библиотечные фичи всё равно используются не из стандарта как такового, а из возможностей конкретной библиотеки (вон, уже до 17-го стандарта дошли, однако энтерпрайзный rhel7 ещё жив, и какой-нибудь std::to_chars там по-прежнему приходится заменять самописным костылём).
В rhel7 есть devtoolset12, так что можно смело пользоваться std::to_chars
.
С такой целью в boost недавно завезли boost-compat. А ещё разработчики компиляторов собираются бэкпортировать import std
в C++20.
А у _ будут какие-то оптимизации?
Я так понял, что это заглушка, которая потом никогда не используется, тогда и тратить время на ее заполнение не имеет смысла в некоторых случаях (например во втором примере кода).
для переменных с именем
_
. Теперь можно писать лаконичный код,который похож на Python:
Вообще-то в Perl же.
Так и хочется добавить меметичное: "I never asked for this", или "остановитесь" :D
После всех этих раздуваний языка, ИМХО тёплый ламповый c++11 выглядит ещё лучше - после него ничего существенно так и не добавили (кроме концептов, ну и модулейк коих редко встретить), как добавили лямбды, enum class, sfinae, move-семантику, constexpr, auto, так ничего радикально нового нет, пока рефлексию не завезут. Почти всё можно выразить через более базовые вещи. Ranges и fmt в stl не в счёт.
Новые потуги втискивания таких "фич" похожи уже на стагнацию, на фоне которой симпатичными становятся более стройные zig'и, rust'ы, cppfront'ы и carbon'ы :D Рефлексии/интроспекции как не было так и нет. Большинство хороших системных либ вроде freetype/harfbuzz/json/stb/sdl/png ... тысячи их, всё-ещё поддерживают именно c++11, если не C90, новых проектов на последних плюсах чёт не видно, редко встречаются робкие переходы на c++17 (и то, потому что, скажем, gtest на него перешел и задал тренд) - проекты на других ЯП, вроде "ржавого" выглядят очень смачно (мне даже приходилось большие либы бэк-портировать на плюсы), и не потому что всё там очень круто, а потому что плюсы понемногу сами-себя закапывают.
Сори за хейт-спич, наболело, и грустно становится, от того, куда движется родной язык.
Сори за хейт-спич, наболело, и грустно становится, от того, куда движется родной язык.
Ничего, все, думаю, уже привыкли слушать подобное нытье. Не появляются новые фичи - "язык не развивается", появляются - "развивается слишком быстро, не так и не туда". Но развить "туда", сделав адекватный proposal и продвинув его, это не для нытиков в каментах, нет.
Не появляются новые фичи - "язык не развивается"
Я помню C++ ещё со времён зарождения, и потом, когда STL была своя для каждого компилятора (BTW, на том же hh и сотоварищи старпёрский коллектив легко вычисляется по "C++, знание STL"). В какой-то момент стало слишком заумно, а потом, после 14, оно перешло в плоскость "этот язык пишут инопланетяне для инопланетян" :-)
Сори за хейт-спич, наболело, и грустно становится, от того, куда движется родной язык.
Грустно, но всё равно используете англицизмы? :D
ну по тому что у вас в С++11 sfinae добавили видно "понимание" вопроса
stackless корутины через базовые вещи никак не выразишь
Благодаря это посту я узнал про fmt::format
:)
Спасибо добрые люди!
опечатка std::ofsteram ofs{"data.txt"};
std::ignore == _ ?
Хех, я надеялся на рефлексию, про нее когда-то так сладко рассказвали.
Было бы здорово корутины еще доработать, чтобы можно было сходу, из коробки, с некоторым предвыбранным promise и пулом потоков, избегая повторений. Все пишут одну и ту же вереницу кода для минимального запуска, при текущем состонии корутин
Эх, все ещё без рефлексии?? По ней что-ниубдь слышно вообще?
Кто-нибудь знает что там про мета-классы? Забыли-забили?
Одна из моих любимых фич C++17 parameter pack + fold expressions. Будет ли продолжение развития этой функциональности ? В Circle есть много замечательных и проработанных идей которые уже хочется.
В рамках работы над рефлексией идёт работа по упрощению метапрограммирования. Комитет старается cвести метапрограммирование и работу с variadic templates/parameters к имеперативному стилю. Чтобы по Args...
можно было итерироваться с помощью for
, обращаться к елементу Args...
по индексу и т.п.
Супер. А прийдёт ли [[unsequenced]] и [[reproducible]] в язык ?
Лучше развивать то что уже есть - просто добавить std::types::* range-like алгоритмы
using namespace std::types;
template<typename... Args>
using my_variant = decltype(
pack<Args...>
| filter([]<typename X>( return is_integral_v<X>; ))
| sort()
| to<std::variant>)::type;
На самом деле так и планируется: рефлексия хочет сделать consteval переменную, которая умеет хранить тип. И тогда можно сделать контейнер из таких переменнх и прогнать его через ranges. Получится как в вашем примере, и кажется даже decltype писать не надо будет
Похоже, что фича с переменной _
, кроме всего прочего, позволит не выдумывать имен для разного рода guards, основанных на RAII. Их единственная функция - быть уничтоженными по выходу из скоупа, поэтому можно будет писать:
{
auto _ = std::scoped_lock(my_mutex);
// critical section
}
Или так (при подходящей реализации defer
):
{
auto res = c_library_resource_new();
auto _ = defer([&res] { c_library_resource_destroy(res); });
// do work with `res`
}
// `res` is destroyed
К слову, код стал бы ещё чище, если можно было бы просто писать:
{
auto = std::scoped_lock(my_mutex);
// critical section
}
Ну можно вот так, даже короче получается:
{
std::scoped_lock _{my_mutex};
// critical section
}
С результатом вызова функции такой фокус уже не пройдёт.
class logger;
class performance_timer;
{
// Длинновато
performance_timer _ { logger, "Scope name" };
}
{
// И так длинновато
performance_timer _ = logger.timer( "Scope name" );
}
{
// Уже лучше
auto _ = logger.timer( "Scope name" );
}
{
// Во, зашибись
auto = logger.timer( "Scope name" );
}
Лучше добавить
auto [...args] = x;
Это к тому же позволит
auto [..., a] = x; // неименованный пак
auto [a, ... args] = x;
Ну и решит заодно проблему неименованных скоп гвардов:
auto [...] = std::lock_guard(mtx);
у нас где-то в хедерах есть такое:
#define SPH_INTERNAL_CONCAT2( a, b ) a##b
#define SPH_INTERNAL_CONCAT( a, b ) SPH_INTERNAL_CONCAT2 ( a, b )
#define SPH_UID( prefix ) SPH_INTERNAL_CONCAT ( prefix, __LINE__ )
#define GUARD SPH_UID ( guard_ )
после этого auto GUARD = ... в целом работают. Костыль, костыльный, конечно. И его никто не использует, потому что криво. Но вот аналог defer вполне в ходу:
template<typename ACTION>
AtScopeExit_T<ACTION> AtScopeExit ( ACTION&& action )
{
return AtScopeExit_T<ACTION> { std::forward<ACTION> ( action ) };
}
#define AT_SCOPE_EXIT( ... ) auto SPH_UID ( tAtExit ) = AtScopeExit ( __VA_ARGS__ )
потом где-то что-то вроде
AT_SCOPE_EXIT ( [this] { Cleanup(); } );
вполне норм и понятно.
В “Concerrency in action“ было создание своего наколеночного hazard pointer. Если хочется прям оптимальной имплементации, можно повкуривать в исходники libcds или folly
Тут же цикл статей от автора libcds @khizmax. Вполне на уровне и по-русски! Вот тут как раз про hazard pointers: https://habr.com/ru/articles/202190/
В следующей (по ссылке) статье цикла - про RCU. А вообще лучше просто весь цикл с начала изучить.
А новые стандарты приносят новые Undefined Behaviour?
struct Data : std::hazard_pointer_obj_base<Data>
Странно видеть такой код в новом стандарте, после того как со всех утюгов доносилось про божественность deducing this и как классно будет жить без C, R и T в CRTP.
А что по абстракциям для корутин, помимо std::generator
, планируются ли вообще?
А кто-то может пояснить, почему механизм хазардов всегда делают глобальным, вместо того, чтобы привязать его например к контейнеру и хранить локально?
Ведь в таком случае при работе с двумя контейнерами у каждого будет свой охранник и это должно положительно сказаться на скорости.
В изначальном предложении была возможность создавать разные hazard pointer domain. Однако в прототипе умудрились так соптимизировать, что разные домены уже не давали щутимого улучшения производительности, и их отложили "на потом"
А есть ли репозиторий с кодом в открутом доступе, где библиотеку для хараздов и прочего пишут, чтобы далее затащить в стандартную? Был бы очень признателен. Сам не нашёл (криво искал, наверное)
Очень хотелось бы посмотреть и попробовать найти и понять оптимизации.
Из того что я видел в libcds или читал у Энтони Уильямса или писал сам - не могу даже представить как можно сделать оптимизации (без серьёзных ограничений).
При локальном хранении хараздов ограничений вообще не требуется, да и синглтоны - это обычно не очень хорошо.
std::scoped_lock l(std::rcu_default_domain());
А это разве вообще валидный код? Из-за most vexing parse это будет интерпретировано, как объявление функции с именем l
, и компиляция завалится из-за того, что CTAD не работает на возвращаемых типах функций.
М? А чем это отличается от
MySuperClass MyObject(1, foo());
?
Тем, что литерал 1
не может быть интепретирован, как имя типа
std::rcu_default_domain() возвращает тоже не тип
MySuperClass MyObject(foo());
так изменится что-то?
std::rcu_default_domain()
сама по себе функциональный тип...
так изменится что-то?
Эта строчка тоже считается объявлением функции.
сама по себе функциональный тип
Такая же, как и foo() выше
Эта строчка тоже считается объявлением функции.
Нет, не считается.https://godbolt.org/z/M89fnEYvn
MySuperClass MyObject(int Param);
MySuperClass MyObject(std::rcu_default_domain_object Domain);
Могут считаться.
А вы замените функцию foo на структуру foo...
И что от этого изменится?
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4953.pdf
rcu_domain& rcu_default_domain() noexcept;
Первые новинки C++26: итоги летней встречи ISO