Комментарии 52
с C++20 люди в комитете активно работают над красотой и лаконичностью языка
Наконец-то до людей начало доходить, что итераторы — это не основа основ, которую надо пихать везде, а просто одна из фич, которая иногда уместна, а иногда нет.
Меня особо порадовало contains
. Прямо планету с места сдвинули такими новведениями, е-мое.
Так, глядишь, лет через 20 и str.split()
появится.
std::ssize_t
Но этого нет в стандарте...
Комитет год назад: мы следуем правилам ISO и вообще, этот ваш онлайн никогда не заменит теплого лампового живого общения, он нам не подходит.
Пандемия: Добрый вечер.
Комитет: Мы переехали в онлайн!
Сообщество: ну хоть так.
А по срокам — непонятно. Группа пока не очень удачно организовала работу на удалёнке.
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 метод std::stacktrace::current(), то это достаточно просто реализоввывается, надо только чтобы пользователь подсунул аллокатор не использующий new, realloc или malloc. Но код получится не очень переносимый, так что core files как правило более удобный вариант.
Как показывает практика, если задаться целью, то вполне можно реализовать AS-safe symbolize и demangle трейсов (в конце концов, где же их выводить, как не в обработчиках сигналов?) — правда, приходится имплементировать это всё с нуля и простыни действительно получаются впечатляющие. Кажется, что по-хорошему как раз в ABI-библиотеке такому коду и место и было бы здорово, если бы новые фичи в стандарте позволяли выкидывать велосипеды, написанные ранее для тех же задач, что берётся решать предложение.
Но попытка хорошая :)
В то же время, когда пользовательский код закладывается на то, что условный memchr
AS-safe — это хождение по грани с опорой на веру в здравый смысл и надежду на лучшее, но у имплементации стандартной библиотеки в этом плане позиция более выигрышная, ведь можно с чистой совестью закладываться на детали этой же самой имплементации.
Так или иначе, ситуация, когда отсутствие AS-safety является багом, заметно отличается от ситуации, когда это фича, прямо следующая из предоставляемого интерфейса. Наверное, никому не было бы плохо от наличия более низкоуровневого не аллоцирующего интерфейса, который хотя бы принципиально возможно реализовать на распространённых платформах с предоставлением дополнительных гарантий и через который выражен интерфейс, предоставляющий пользователю std::string
.
Да, можно добавить дополнительный интерфейс наряду со std::stacktrace, но гарантий по нему никаких не давать и делать он будет приблизительно то же, что и std::stacktrace, но очень неудобным способом. Идея весьма сомнительная, удачных примеров такого подхода я не знаю, поэтому в рамках P0881 мы её и не продвигали.
Если хотите подобное в стандарте — готов помочь советом и с написанием предложения в комитет. Но основная работа по проработке прототипа и написанию черновика предложения — на вас.
Если у вас есть идеи, как это исправить не ломая обратную совместимость и как при этом регистронезависимые трейты будут выдавать true при сравнении SS и ß — обязательно пишите на stdcpp.ru. Ну или прям сюда
Ну и std::stacktrace никак не влияет на скорость вызовов функций.
Именно поэтому и говорят, что исключения не добавляют накладных расходов по CPU, если вы их не выкидываете.
Проблема с исключениями в том, что:
- Жрут немало памяти, даже если их не используешь.
- Слишком большие расходы при бросании. Мало того, что проходится по таблицам, так и еще берутся блокировки на эти таблицы, причем не на чтения, а эксклюзивные. Таким образом, в многопоточном коде внезапно исключения из одного потока влияют на исключения в другом.
Да и вообще, сама идея блокировок при однопоточном характере исключений — крайне странно и выглядит как баг.
2. Блокировки убрали в более новых c++ runtime, для случаев когда вы не используете dlopen.
В тоже время сам компилятор 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 в большой иерархии функции достаточно легко прежде всего для себя гарантировать отсутвие нежелательных сайд эффектов во всей иерархии вызовов, или быстро их отрефакторить после того как компилятор их все подсветит.
Думаю, весьма компромиссный вариант — добавить все эти проверки в clang-tidy, чтобы не замедлять компилятор. // Есть ли вообще причины в 2020 не собираться с clang-tidy?
Начиная с C++20 заголовочные файлы стандартной библиотеки могут использоваться как «модули с макросами», например import <iostream>. Использование в виде «безмакросных модулей», например import std.iostream, ожидается к C++23
www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html
Я попытался добавить определение 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.
…
Думаю пока официальной поддержки Майкрософта нет, то и без толку говорить о стандартизации…
Ждем пока Майкрософт люди проснутся…
С++23: международный стандарт на удалёнке