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

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

с C++20 люди в комитете активно работают над красотой и лаконичностью языка

За время, пока string::contains добрался до стандарта, родилось, выросло и умерло примерно 4 поколения таких котиков.
Наконец-то до людей начало доходить, что итераторы — это не основа основ, которую надо пихать везде, а просто одна из фич, которая иногда уместна, а иногда нет.

Меня особо порадовало contains. Прямо планету с места сдвинули такими новведениями, е-мое.

И одно поколение разработчиков. =)

Так, глядишь, лет через 20 и str.split() появится.

Просто замечательно! А что на счет strip, rstrip, (trim)?
Ждём ещё 20 лет

Легко через range-фильтры реализуются

std::ssize_t

Но этого нет в стандарте...

Спасибо, поправил

А почему нет, кстати? Особенно учитывая наличие функции std::ssize.

Когда делали ssize() В стандарте уже был std::ptrdiff_t. Авторы предложения не захотели вводить новую сущность.
Сообщество год назад: доколе развитие языка будет тормозиться необходимостью личного присутствия? Это нелепо. Все необходимое есть онлайн.

Комитет год назад: мы следуем правилам ISO и вообще, этот ваш онлайн никогда не заменит теплого лампового живого общения, он нам не подходит.

Пандемия: Добрый вечер.

Комитет: Мы переехали в онлайн!

Сообщество: ну хоть так.
ISO поменяло правила :)

Вся стандартизация переехала в онлайн, не только C++
image
Z и UZ это несомненно очень круто, но что там с рефлексией?
Появился большой документ о метапрограммировании и рефлексии. Там расписано общее направление, обзор отдельных возможностей, анализ взаимодействия разных частей и проч. Рекомендую :)

А по срокам — непонятно. Группа пока не очень удачно организовала работу на удалёнке.
А есть что-нибудь на тему компайл-тайм переменных? Ну типа
struct S { 
  constexpr S() : v(7) {} 

  varexpr int v; 
};

S s;
static_assert(s.v == 7, "Initialization error."); 
... 
s.v = s.v + 42; // evaluates in compile-time
static_assert(s.v == 49, "Evaluation error.");

Выглядит как странная и неотлаживаемая дичь, честно говоря

В предложении говорится, что async-signal-safety не гарантируется (что в целом разумно, учитывая, что не на всех платформах это словосочетание вообще имеет смысл). Тем не менее, стоит ли ожидать, что имплементации std::stacktrace под условный x86-64 GNU/Linux будут допускать использование в обработчиках сигналов?

async-signal-safe вывод трейсов потребовал бы огромных трудозатрат. Например, деманглинг имён функций обычно реализовывается через abi::__cxa_demangle, а он аллоцирует, что не async-signal-safe. И таких проблем сотни. Поэтому интерфейс не предполагает такое использование в принципе, везде возвращается удобные пользователю типы std::string или используются iostreams.

Если же интересует async-signal-safe метод std::stacktrace::current(), то это достаточно просто реализоввывается, надо только чтобы пользователь подсунул аллокатор не использующий new, realloc или malloc. Но код получится не очень переносимый, так что core files как правило более удобный вариант.

Как показывает практика, если задаться целью, то вполне можно реализовать AS-safe symbolize и demangle трейсов (в конце концов, где же их выводить, как не в обработчиках сигналов?) — правда, приходится имплементировать это всё с нуля и простыни действительно получаются впечатляющие. Кажется, что по-хорошему как раз в ABI-библиотеке такому коду и место и было бы здорово, если бы новые фичи в стандарте позволяли выкидывать велосипеды, написанные ранее для тех же задач, что берётся решать предложение.

Этот код не async-signal-safe, проблемы в некоторых методах libc. Заводили багрепорты на libc, которые до сих пор не поправлены.

Но попытка хорошая :)

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


Так или иначе, ситуация, когда отсутствие AS-safety является багом, заметно отличается от ситуации, когда это фича, прямо следующая из предоставляемого интерфейса. Наверное, никому не было бы плохо от наличия более низкоуровневого не аллоцирующего интерфейса, который хотя бы принципиально возможно реализовать на распространённых платформах с предоставлением дополнительных гарантий и через который выражен интерфейс, предоставляющий пользователю std::string.

Этот вопрос обсуждался в комитете. Основная проблема — как минимум на одной очень популярной платформе невозможно это реализовать в принципе.

Да, можно добавить дополнительный интерфейс наряду со std::stacktrace, но гарантий по нему никаких не давать и делать он будет приблизительно то же, что и std::stacktrace, но очень неудобным способом. Идея весьма сомнительная, удачных примеров такого подхода я не знаю, поэтому в рамках P0881 мы её и не продвигали.

Если хотите подобное в стандарте — готов помочь советом и с написанием предложения в комитет. Но основная работа по проработке прототипа и написанию черновика предложения — на вас.
Ходят непроверенные слухи, что contains будет регистрозависимый, и передача туда своего компаратора не предусмотрена. Это баг или фича? Если фича, то почему?
Это последствия дизайна std::basic_string, в который вшиваются char_traits и используются одинаковые трейты для всех операций. Компаратор нельзя передать и в более базовые операции, например std::string::find.

Если у вас есть идеи, как это исправить не ломая обратную совместимость и как при этом регистронезависимые трейты будут выдавать true при сравнении SS и ß — обязательно пишите на stdcpp.ru. Ну или прям сюда
НЛО прилетело и опубликовало эту надпись здесь
Имплементации должны предоставлять выбор поведения через link-time флаг. Так что да, как и в Boost.Stacktrace, будет возможность превращать stacktrace в noop.

Ну и std::stacktrace никак не влияет на скорость вызовов функций.
НЛО прилетело и опубликовало эту надпись здесь
Например, переиспользует unwind-tables от исключений, см Boost.Stacktrace. И не надо на стек ничего лишнего класть
НЛО прилетело и опубликовало эту надпись здесь
unwind-tables не так работают. Они заполняются на этапе компиляции, при заходе в фрейм ничто в них не пишется и не читается. При обычном выходе из фрейма — тоже ничего не делается.

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

Проблема с исключениями в том, что:


  1. Жрут немало памяти, даже если их не используешь.
  2. Слишком большие расходы при бросании. Мало того, что проходится по таблицам, так и еще берутся блокировки на эти таблицы, причем не на чтения, а эксклюзивные. Таким образом, в многопоточном коде внезапно исключения из одного потока влияют на исключения в другом.

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

1. В компиляторах идёт работа по улучшению размера итогового кода для исключений (компилирование кода для исключений с оптимизацией под размер, а не под скорость; более аккуратное и правильное проставление cold path с вынесением его отдельно от hot path; оптимизации для замены механизма исключений более простым кодом и т.д.).
2. Блокировки убрали в более новых c++ runtime, для случаев когда вы не используете dlopen.
не было обсуждения о смене ABI ради прироста в производительности?
Так вроде от этого уже отказались по результатам голосования ещё до оффициального принятия С++ 20.
Как правильно поучаствовать в обсуждении pure функций? изучил 3 существующих пропозала, есть идеи как сделать их более полезными.
Можно здесь пообсуждать, можно в чате, можно на stdcpp.ru

А что за идеи?
Существующие пропозалы наследуют идею из компилятора g++ в том или ином виде.

В тоже время сам компилятор g++ хоть и предоставляет механизм подсказок для маркировки функций как pure/const, но не предоставляет механизма для валидации, например, ситуаций когда функция была pure но в какой то момент перестала ей быть. Таким образом программа перестает работать правильно, и это скрыто в компайл тайме. Тем самым девальвируется ценность данного функционала и в плохих руках он становится скорее вредным.

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

Как пример, разработчик алгоритма вида: reduce_non_blocking(T func), может захотеть ограничить концептом лишь pure функции в качестве аргумента. Тем самым защитив на этапе компиляции от множества потенциальных проблем себя и пользователя библиотеки.

В самом языке уже есть точно такая же идея, только реализованная не через атрибуты и не через decltype и это — const qualifier. С одной стороны квалификатор разрешает лишь subset языка C++ внтури метода. С другой стороны перегружает функции и позволяет валидировать тип аргумента. И одновременно является сигнатурой функции.
В самом языке уже есть точно такая же идея, только реализованная не через атрибуты и не через decltype и это — const qualifier. С одной стороны квалификатор разрешает лишь subset языка C++ внтури метода. С другой стороны перегружает функции и позволяет валидировать тип аргумента. И одновременно является сигнатурой функции.
с одной стороны да, можно рассматривать pure как более сильный const. Но идея расширять правила перегрузок в с++ почти универсально плохая — они и так шибко уж сложные.
Но идея расширять правила перегрузок в с++ почти универсально плохая — они и так шибко уж сложные.

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

С другой стороны, если посмотреть на места где именно «нужен» pure, а не хотелось бы что бы он был. Для меня — это проекты где миллионы строк математического кода которому уже десятки лет. И где клиенту нужно внедрить многопоточность, а для разработчика написав pure в большой иерархии функции достаточно легко прежде всего для себя гарантировать отсутвие нежелательных сайд эффектов во всей иерархии вызовов, или быстро их отрефакторить после того как компилятор их все подсветит.

В FORTRAN были чистые функции и модули… ещё в 90/95 стандартах

Аналогичные проверки можно добавить и к noexcept, но нарушится требование обратной совместимости.
Думаю, весьма компромиссный вариант — добавить все эти проверки в clang-tidy, чтобы не замедлять компилятор. // Есть ли вообще причины в 2020 не собираться с clang-tidy?
Мне кажется или С++ становится PL/1?
А что там с контрактами? И будет ли stl, наконец, реализована с помощью модулей?
Контракты отправили на переработку. Когда появится переделанный вариант — неизвестно.

Начиная с C++20 заголовочные файлы стандартной библиотеки могут использоваться как «модули с макросами», например import <iostream>. Использование в виде «безмакросных модулей», например import std.iostream, ожидается к C++23
Большое спасибо. Надеюсь контракты в С++ 23 появятся, их очень сильно не хватает.
У идеи нет реализации, множество подводных камней и недостаточная мотивация. Предложение рассматривалось два раза и оба раза было встречено весьма прохладно. После второго раза (4 года назад), автор не обновлял идею.
Я боюсь что stacktrace в том виде как он сейчас сделан, не работает для C++-C# совместимых stacktraceов.

Я попытался добавить определение call stackа с учетом C# / C++/call конверсий — мой собственный форк: github.com/tapika/stacktrace

Но определение C# call stacka в symbol naming по прежднему отсутствует.

FYI:

Meanwhile — I've tried another library — Microsoft.Diagnostics.Runtime — github.com/microsoft/clrmd, written in C#,
and what I have tested — boost::stacktrace can return native c++ symbols (on windows) and clrmd works with managed stack frames.

Basically if I want to recollect full stack trace — best way is to use combined runtime — potentially parts from C++ (boost stack trace or similar)
and potentially parts from C# — e.g. clrmd fork for example.

I had also short chat with one of the authors — if you want — you can read it from here:
github.com/microsoft/clrmd/issues/847


What I've briefly checked clrmd — I like that almost all windows api are available — even for querying IDebugSymbols,
so one approach is to write everything in C#. I would prefer to have clean C++ code and clean C# code side by side — just in case
if we identify some of bottlenecks in some environment.


Думаю пока официальной поддержки Майкрософта нет, то и без толку говорить о стандартизации…

Ждем пока Майкрософт люди проснутся…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий