Обновить
245
0
Antony Polukhin @antoshkka

Эксперт-разработчик C++

Отправить сообщение

Случай с embed показателен в плане медлительности и неэффективности комитета стандартизации.

А на мой взгляд это успех - забраковали первые версии embed, которые ломали сборку и разработку множеству компаний; подсказали что правильнее реализовывать функционал через препроцессор и для лучшей совместимости лучше реализовать для C стандарта; полученный из комитета C #embed отревьюили опять, поправили проблемы, приняли в C++ и отправили в C изменения для синхронизации.

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

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

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

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

Идее relocate больше 20 лет :) Во многих библиотеках подобный подход использовался и кастомизировался с помощью специфичных для библиотеки трейтов. Предложение по relocate просто стандартизирует способ подобного указания.

Рефлексия движется крайне быстро. Я вообще удивлён что так молниеносно удалось 4 различные популярные реализации C++ фронтенда свести к общей части - рефлексии.

Это UB, как если бы позвали

auto x = std::make_unique<int>();
std::destroy_at(&x);

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

Толкать метаинформацию, влияющую на ABI через атрибуты на практике получается неприятно. Комитету не понравилось как получилось с [[no_unique_address]], поэтому больше так делать не хотят. Контекстно зависимое ключевое слово в этом плане лучше - точно применится или будет ошибка компиляции, проще диагностировать неправильные использования.

Ну а что касается вкусовщины - излишнее количество [[]] не идёт языку на пользу. Читается хуже и язык превращается из C++ в C[[]] %)

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

В имени аргумента if_eligible не просто так. Компилятор проверит что все члены класса тоже trivially_relocatable, и только тогда трейт будет возвращать что класс действительно тривиально релоцируемый. Например:

template <class T>
class optional trivially_relocatable_if_eligible {
  union {
    Empty empty{};
    T payload;
  } data_;
  // ...
};

Приведённый optional будет trivially_relocatable если ABI платформы разрешают делать trivially_relocatable юнионы и T является trivially_relocatable.

Нет по дефолту поведения UB на контракте

Этот режим "вынули" из C++26. Дальше в планах его добавить, чтобы компилятор мог оптимизировать из расчёта на то, что контракт никогда не нарушается.

Более того, я уже вижу как их будут использовать:

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

#define LOGME std::print(std::stacktrace::current().front().name())

void foo(int i) {
  LOGME;
  ...
}

lifetime relocate-нутого объекта завершён. Его больше нет, так что обращение будет старым добрым UB.

На этапе компиляции ведь файл там же где и был во время препроцессинга

Кажется что тогда сломается кеширование объектников по хешу препроцессирования - изменение ресурса не будет приводить к пересборке. А значит сломается ccache и куча аналогичных enterprise решений

С атрибутом будет длиннее на 4 символа т.к. `[[]]` :)

Все старые правила по оптимизациям тривиальных типов в компиляторе остаются. Если нет особой нужны различать trivially_relocatable|nothrow movable|trivial, то в стандартную библиотеку в том же P2786 добавили std::relocate(from_begin, from_end, to), который для Point так же превратится в std::memmove.

Safe C++ в своих примерах использует `#feature`, который является аналогом профилей. Так что комитет прежде всего сконцентрируется на профилях, при этом borrow checking (P3390 Safe C++) будет развиваться параллельно.

Есть небольшой шанс увидеть Safe C++ в C++29, но работа предстоит титаническая

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

На мой взгляд - темпы внедрения новых фичей просто бешеные. Посмотрите на другие языки со стандартом - некоторые стандарты 90х годов в них до сих пор не реализованы.

Ну сами изменения в C++ достаточно фундаментальные. Например C++20 модули затрагивают всю инфраструктуру C++ (компиляция, линковка, системы сборки, пакетные менеджеры, IDE, написание кода...). Одно это нововведение сравнимо по масштабам с Python2 -> Python3 (но при этом не ломает обратную совместимость).

Спасибо!

В userver запросы тоже превращаются в prepared statements и параметры шлются отдельно от текста запроса в бинарном виде, что избавляет от sql injection. Но да, автогенерилки запросов у нас нет (имхо, написать на SQL запрос проще чем учить специфичный для библиотеки DSL; но пользователям фреймворка хочется такой DSL иметь)

linq2db

На первый взгляд (посмотрел первые насколько туториалов) весь функционал спокойно реализуется через compile time рефлексию (получение имён полей, доступ к полям, маппинг из базы на структуру... большинство этого уже сейчас можно делать с помощью Boost.PFR и мы пользуемся подобным в userver при работе с базами данных).

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

Это решается через std::function<bool(const data&)>, или у вас какой-то особо сложный случай? Дайте пожалуйста побольше подробностей.

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

А приведите пожалуйста такой пример

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

Предложение обсуждалось в скользь, с тех пор идёт занятная работа по прототипированию в различных компиляторах (см JIT в GCC, и кажется в LLVM тоже делают).

А там имеется поддержка C++ компилятора, или только C?

В C++26 есть все шансы увидеть #embed https://wg21.link/P1967

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

почему вообще баяны и моноброви добавляют, вместо четкого и понятного словестного обозначения? Ключевое слово или как-то еще?

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

Информация

В рейтинге
Не участвует
Откуда
Россия
Работает в
Зарегистрирован
Активность