До C++20 осталась пара лет, а значит, не за горами feature freeze. В скором времени международный комитет сосредоточится на причёсывании черновика C++20, а нововведения будут добавляться уже в C++23.

Ноябрьская встреча в Сан-Диего — предпоследняя перед feature freeze. Какие новинки появятся в C++20, что из крупных вещей приняли, а что отклонили — всё это ждёт вас под катом.



char8_t


Добавили новый тип данных char8_t. Массив этих символов представляет собой UTF-8 строку:

std::u8string hello = u8"Привет, мир!";

// TODO: Вывести значение пока нельзя!
//std::cout << hello; 

На первый взгляд кажется, что нововведение незначительное. Но это не так.

char8_t — первый шаг к тому, чтобы стандартная библиотека C++ из коробки поддерживала UTF-8. Впереди ещё много работы, к C++20 она явно не завершится.

Однако уже теперь char8_t многим превосходит char/unsigned char. Программы, использующие char8_t, могут работать быстрее за счёт того, что char8_t не алиасится с другими типами данных. Иными словами, модификация строки или любой переменной не приведёт к тому, что значения переменных будут перечитываться из памяти:

bool do_something(std::u8string_view data, int& result) {
    result += data[0] - u8'0'; // переменная result изменилась
    return data[0] != u8'0'; // будет использовано значение из регистра для data[0] 
}

Если бы мы в примере взяли char (std::string_view), то получили бы код, в котором несколько раз обращаемся к BYTE PTR [rsi]. В случае char8_t это не происходит.

Учтите, что теперь u8«hello» — это массив chat8_t, а не массив char. Данное изменение в стандарте ломает обратную совместимость с C++11/14/17! Полный список изменений связанных с char8_t доступен в документе P0482. В этом же документе есть список примеров, когда валидный до C++20 код становится невалидным из-за char8_t.

constexpr


К C++20 многие (и я в их числе) хотят увидеть в стандарте контейнеры, которыми можно пользоваться на этапе компиляции. Это позволит делать меньше вычислений на runtime, а значит, при работе приложения будет тратиться меньше процессорного времени. При этом, зачастую, вам не придётся ничего менять в исходниках — всё просто начнёт работать быстрее, инициализироваться на этапе компиляции, лучше оптимизироваться компилятором…

В Сан-Диего сильно расширили возможности компилятора и стандартной библиотеки по вычислению выражений на этапе компиляции:

  • try и catch теперь можно писать в constexpr функциях (P1002).
  • dynamic_cast и typeid можно вызывать в constexpr (P1327).
  • Добавили consteval-функции (бывшие constexpr!) — функции, которые можно вычислять только в constexpr контексте (P1073).
  • Добавили функцию std::is_constant_evaluated(), возвращающую true, если в данный момент функция вычисляется на этапе компиляции P0595. Старайтесь без крайней надобности не пользоваться std::is_constant_evaluated(): она очень своеобразна.
  • Менять активное поле union теперь так-же можно при constexpr вычислениях (P1330).
  • Невообразимое множество классов и функций стандартной библиотеки теперь помечены как constexpr. Они смогут вычисляться на этапе компиляции (P1032, P1006).

На следующем заседании, которое пройдёт в США 18–23 февраля 2019 года, планируется добавить контейнерам std::string, std::vector (и возможно std::map) возможность работать на этапе компиляции.

Все добавления и правки жизненно важны для готовящейся к C++23/26 рефлексии.

Прочие мелочи


Гетерогенные поиски в unordered контейнерах


Начиная с C++20 можно будет дополнительно настраивать unordered контейнеры и обязывать их не конструировать временные объекты при операциях поиска:

struct string_hash {
  // Без следующей строчки будут создаваться временные объекты!
  using transparent_key_equal = std::equal_to<>; 

  size_t operator()(std::string_view txt) const { return std::hash<string_view>{}(txt); }
};

using unordered_set_string = std::unordered_set<std::string, string_hash, std::equal_to<> >;

template <class Value>
using unordered_map_string 
    = std::unordered_map<std::string, Value, string_hash, std::equal_to<> >;
// ...
unordered_map_string<int> map = { /* ... */};
assert(map.contains("This does not create a temporary std::string object :-)"));

Вещь весьма полезная, детали можно найти в документе P0919.

std::bind_front


Уже давно считается, что std::bind — достаточно опасная вещь, из-за которой легко пораниться. Поэтому в C++20 добавили более простую функцию std::bind_front.

Она не поддерживает placeholders, правильно работает с ref-qualifiers и компилируется немного быстрее. Пользоваться ей можно будет приблизительно вот так:

int foo(int arg1, std::string arg2, std::vector<int>&&, std::string_view);
// ...
auto bound = std::bind_front(foo, 42, "hello");
// ..
int result = bound(std::vector{42, 314, 15}, "word");

Всеобъемлющее описание есть в документе P0356.

std::assume_aligned


Ура, теперь можно подсказывать компилятору, что данные у нас выравнены:

void add(span<float> x, float addition) {
    const auto size = x.size();
    float* ax = std::assume_aligned<64>(x.data());
    for (int i = 0; i < size; ++i)
        ax[i] += factor;
}

Это поможет компилятору автоматически векторизовать циклы и генерировать более производительный код. Дополнительные примеры можно найти в документе P1007.

void foo(const Concept auto& value)


В P1141 приняли сокращённый синтаксис для записи шаблонных функций и классов, аргументы которых должны соответствовать концепту. Например, void sort(Sortable auto& c); значит, что sort — это шаблонная функция, и что тип переменной `c` соответствует концепту Sortable.

Микро-оптимизации


Классы std::optional и std::variant теперь обязаны иметь тривиальные деструкторы, copy/move конструкторы и copy/move операторы присваивания, если шаблонные параметры классов обладают свойствами тривиальности. Это немного поможет компилятору и стандартной библиотеке генерировать более производительный и компактный код (P0602).

Move-конструктор std::function теперь обязан быть noexcept. Если у вас есть std::vector<std::function> и конструкторы std::function раньше не были noexcept, то работа с таким вектором станет в несколько раз производительнее (P0771).

Если вы имели дело с большими массивами чисел и иcпользовали make_unique/make_shared, то иногда производительность слегка проседала за счёт того, что каждый элемент массива инициализировался нулём. Некоторые специально писали new T[x], чтобы не инициализировать каждое значение. Так вот, в C++20 добавили std::make_unique_default_init и std::make_shared_default_init. Эти две функции приехали из Boost и они не делают лишней инициализации (P1020).

Ещё добавили *_pointer_cast функции, принимающие rvalue. Это помогает избегать лишних инкрементов и декрементов атомарного счётчика при работе с std::shared_ptr (P1224).

Исправления


В великолепном документе P0608 убрали боль при использовании std::variant:

std::variant<std::string, bool> x = "abc";    // Ой! До C++20 `x` содержит `true`

Ещё один великолепный документ P0487 того же автора избавляет от граблей, на которые очень многие наступали:

char buffer[64];
std::cin >> buffer;    // Теперь гарантированно не переполняется
char* p = get_some_ptr();
std::cin >> p;            // Теперь просто не компилируется

Наконец, решили, что в контрактах автор класса имеет право использовать приватные члены класса в условиях контракта (P1289):

struct int_reference {
   // ...
   int get() const [[expects: ptr_ != nullptr ]] { return *ptr_; }
private:
   int* ptr_;
};

Networking


Итак, приступим к крупным нововведениям. И начнём с плохого: в C++20 нам не видать работы с сетью из коробки. Отложили на неопределённый срок.

Modules


К хорошим новостям — подгруппа EWG одобрила дизайн модулей, так что есть все шансы увидеть их в C++20. Финальная битва за модули предстоит на следующем заседании.
О скорости сборки и модулях
Учтите, что из коробки модули не дадут вам большой прирост скорости сборки.

Ближайшие года уйдут у разработчиков языка C++ на оптимизации компиляторов для работы с модулями и на оптимизацию представления модуля.

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

Ranges


Ranges в C++20 приняли. На голосовании в последний день авторы предложения P0896 сорвали долгие овации. Весь зал аплодировал стоя. Начало оваций даже успели сфотографировать, счастливый автор предложения — в шапке этого поста.

Вот пара примеров того, что можно делать с ranges:

#include <algorithm>

std::ranges::sort(some_vector);
std::ranges::find(email.c_str(), std::unreachable_sentinel, '@');
std::ranges::fill(std::counted_iterator(char_ptr, 42), std::default_sentinel, '!');

Coroutines


Возвращаемся к тому, что не приняли. Coroutines не вошли в стандарт на голосовании. Возможно, это случится на следующем заседании, но шансов маловато.

Немного инсайда
Разработчк Boost.Beast твёрдо решил взяться за альтернативное предложение по сопрограммам. Они будут похожи на обычные функции, их размер будет известен на этапе компиляции, они не будут динамически аллоцировать память… но будут требовать, чтобы всё тело resumable функции было видно в месте использования корутины.

Хорошо это или плохо, подоспеет ли прототип к следующему заседанию — это открытые вопросы.

2D Graphics


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

Заслуги РГ21


На заседании мы в основном дотаскивали stacktrace (который мы в Яндекс.Такси очень любим) до стандарта C++. Сейчас черновик документа выглядит вот так. Надеюсь, что осталось совсем чуть-чуть, и к C++20 успеем.

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

Ещё мы пытались привнести в стандарт плагины (динамическую загрузку библиотек, идея с stdcpp.ru). Тут нас ждал провал — предложение отклонили. Учтём ошибки и попробуем позже.

Наше старое предложение добавить атрибут [[visible]] для упрощения создания динамических библиотек, внезапно подхватил другой разработчик в документе P1283. Всячески поддерживали документ на голосованиях, первую подгруппу прошли, надеемся на успех.

Идею упростить работу с std::variant, а именно «Добавить операторы сравнения std::variant с его элементами», так же отклонили. Основные возражения — пока боязно менять std::variant, учитывая его проблемы с конструкторами (хотя после P0608) они исчезнут. Попробуем ещё раз.

С конкурентным unordered map (P0652) наоборот, всё было достаточно гладко: нам порекомендовали проверить пару альтернативных интерфейсов и сказали, что предложение почти готово для принятия в Concurrent Data Structures TS (правда, он пока только планируется).

В подгруппе SG6 Numerics мы прошлись по большинству имеющихся идей, предложили и немного обсудили механизм взаимодействия различных классов чисел (P0880). Ждём, когда начнут создавать Numbers TS, куда должны попасть все новые и вкусные классы чисел.

В подгруппе по ядру языка мы презентовали идеи о «Беспредельном copy elision», а именно P0889. Люди очень хотят нечто подобное, но не в том виде, что было изложено. Нас отправили напрямую к разработчикам компиляторов за консультацией.

Ну и, как упоминалось выше, нашу бумагу Misc constexpr bits P1032, приняли в C++20. Теперь можно будет использовать на этапе компиляции array, tuple, pair, всё что нужно для копировании std::string, back_insert_iterator, front_insert_iterator, insert_iterator.

Вместо итогов


C++20 обещает быть весьма занятным: Concepts, Contracts, Ranges, Modules, работа с временными зонами и множество constexpr нововведений.

В скором времени мы, Рабочая Группа 21, отправим комментарии к черновику стандарта C++20. Поэтому, если у вас есть какая-то боль, или вы не согласны с каким-то нововведением, пожалуйста, оставляйте свои мысли на этой странице.

Также приглашаем вас на наши ближайшие встречи по C++: Открытая встреча РГ21 в Москве и Санкт-Петербурге и C++ Siberia 2019 в Новосибирске.

Комментарии (156)


  1. exception13x
    28.11.2018 09:53
    +1

    Есть новости, когда планируется отказаться от хэдеров и препроцессора?


    1. antoshkka Автор
      28.11.2018 10:38

      Нужно чтобы все проекты переехали на модули, тогда и можно будет отказываться (другими словами — не раньше C++35)


      1. babylon
        29.11.2018 00:20

        Сделали бы нативный аллокатор в нотации MessagePack. На модули перейдут неизбежно.


        1. antoshkka Автор
          29.11.2018 08:35

          Расскажите поподробнее про аллокатор. Чем он хорош?


          1. babylon
            30.11.2018 01:19

            Его в природе не существует… MessagePack предназначен для упаковки объекта, но многого с этим упакованным объектом поделать нельзя. Вот если бы сделали аллокатор то можно было дампить напрямую, модифицировать, разбирать и собирать на эндах, "шардить", парсить в AST и т.д. Всё как мы любим. Я за себя говорю. Я бы нашел ему применение это точно.


    1. VioletGiraffe
      28.11.2018 12:16

      Без макросов некоторые вещи не делаются, когда будут делаться, тогда и можно отказываться. Вещи, связанные с удобным для программиста генерированием повторяющегося исходного кода.


      1. kovserg
        28.11.2018 12:39

        Интересно, а идей улучшить препроцессор вместо того что бы хаить макросы не возникало?


        1. antoshkka Автор
          28.11.2018 12:49

          А как именно вы предлагаете его улучшить?


          1. Gorthauer87
            28.11.2018 14:28

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


            1. antoshkka Автор
              28.11.2018 14:32

              А расскажите поподробнее, как вы видите подобные макросы в C++?


              1. Gorthauer87
                28.11.2018 23:03

                1. Antervis
                  29.11.2018 03:14
                  +1

                  вы пропустили важную деталь:

                  А расскажите поподробнее, как вы видите подобные макросы в C++?

                  т.е. без конфликтующего синтаксиса, breaking changes и чтобы был прок


                  1. Gorthauer87
                    29.11.2018 09:51

                    Мне казалось, что функции с восклицательным знаком запрещены в плюсах. Соответственно их никто не может писать, а если на них сделать макросы, то нигде совместимость не сломается


                    1. Antervis
                      30.11.2018 01:24

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


                      1. mapron
                        30.11.2018 12:24

                        То что я выше посмотрел по ссылке, не рефлексию больше напоминает, а generator expressions, которые позволяют ast менять, очень для метаклассов будут полезны. Но это точно не C++23, как Саттер сказал. Может быть какой-то TS к 26 году разве что.


                1. IRainman
                  30.11.2018 18:02

                  Это всё опять же «такое себе решение».Нужно элементарное: больше базового синтаксиса на этапе компиляции тогда и макросы станут не нужны.

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

                  <typename T>
                  ... some_func(..., T x, ...)
                  ...
                  if (exist(x.getList))
                  {
                  ... код который даже не скомпилируется без метода getList у типа T
                  }
                  ...
                  ...
                  

                  Всё упирается в элементарное if этапа компиляции которое могло бы выключить кусок функции если у нас в классе есть метод для получения одного элемента и нет метода для получения коллекции.

                  P.S. в идеале хотелось бы даже шаблон не создавать, но это уже совсем мечты.


                  1. antoshkka Автор
                    30.11.2018 18:14
                    +1

                    Так уже можно:

                    template <class T>
                    concept Listable = requires(T x) {
                         x.getList();
                    };
                    
                    <typename T>
                    ... some_func(..., T x, ...)
                    ...
                    if constexpr(Listable<T>)
                    {
                    ... код который даже не скомпилируется без метода getList у типа T
                    }
                    ...
                    ...
                    


      1. DistortNeo
        28.11.2018 17:58

        Вещи, связанные с удобным для программиста генерированием повторяющегося исходного кода.

        Можете привести пример кода, который невозможно сгенерировать с помощью шаблонов и constexpr?


        1. eao197
          28.11.2018 18:25

          Регулярное выражение?


          1. DistortNeo
            28.11.2018 18:48

            А как их можно макросами реализовать?

            А вот constexpr — пожалуйста:
            github.com/hanickadot/compile-time-regular-expressions


            1. eao197
              28.11.2018 19:03

              А как их можно макросами реализовать?
              Плюсовыми — никак. А вот с макросами вроде Rust-овских или Nermele-овых вполне себе.
              github.com/hanickadot/compile-time-regular-expressions
              Так затем в рантайме все равно приходится работать со string-view и формировать из результатов разбора нужные значения.

              Вот на продвинутых макросах (или на D-шных CTFE+mixin), гипотетически, можно получить что-то вроде:
              auto [year, month, day] = $super-puper-macro("^(?<year:short>[0-9]{4})/(?<month:byte>[0-9]{1,2}+)/(?<day:byte>[0-9]{1,2}+)$").match(s)
              

              где year будет иметь тип int, а month и day — тип byte.


          1. domix32
            28.11.2018 19:04

            Какой-нибудь кейс когда проще написать макрос нежели шаблон/функцию для регулярки?


        1. Amomum
          28.11.2018 19:03

          if( error ) return error;
          и прочие модификации control-flow?
          Конкатенация строк в названиях переменных?


          1. DistortNeo
            28.11.2018 20:48

            Не вижу в этом ничего хорошего. Код пишется один раз, зато читается постоянно. Упрощение написания кода ценой усложнения его чтения и отладки — это выстрел в ногу.


            1. Amomum
              28.11.2018 21:29

              Вы просили пример — я его привел :) Я не говорю, что это хорошо, но на шаблонах и лямбдах так не сделать.


        1. 0xd34df00d
          28.11.2018 20:59

          Сегодня или с рефлексией?


          Если сегодня, то BOOST_FUSION_ADAPT_STRUCT и подобные, например.


        1. Adler3D
          29.11.2018 10:17

          Можете привести пример кода, который невозможно сгенерировать с помощью шаблонов и constexpr?

          #define LIST(F)F(int,a)F(bool,b)F(char,c)F(string,d)
          struct t_foo{
            #define F(TYPE,NAME)TYPE NAME;
            LIST(F)
            #undef F
            void use_func1(){
              #define F(TYPE,NAME)::func1(#TYPE,this->NAME);
              LIST(F)
              #undef F
            }
            void use_func2(){
              #define F(TYPE,NAME)::func2(#TYPE,this->NAME,#NAME);
              LIST(F)
              #undef F
            }
          };
          #undef LIST


          1. DistortNeo
            29.11.2018 10:59

            Спасибо, хороший пример, что отсутствие рефлексии в C++ — это плохо. Но альтернатива с variadic templates и string literals таки возможна:
            habr.com/post/243581


        1. svr_91
          29.11.2018 17:09

          А какие-нибудь замены макросам __FILE__, __LINE__ уже придумали?


          1. antoshkka Автор
            29.11.2018 17:23
            +1

    1. DistortNeo
      28.11.2018 17:55
      +3

      От препроцессора отказаться невозможно в принципе, т.к. без условной компиляции не обойтись. Но я бы хотел, чтобы действие директив препроцессора ограничивалось только одним файлом. Именно файлом, а не translation unit.


      1. Punk_Joker
        28.11.2018 19:23

        А constexpr (в С++17) разве не позволяет организовывать условную компиляцию?


        1. antoshkka Автор
          28.11.2018 19:41
          +1

          `if constexpr` позволяет


          1. 0xd34df00d
            28.11.2018 21:01
            +3

            if constexpr, увы, не позволит сделать что-то вроде


            #ifdef Q_OS_LINUX
            #include "linuxbackend.h"
            #elif defined(Q_OS_WIN32)
            #include "windowsbackend.h"
            ...
            #endif

            Да и без выкрутасов что-то вроде


            void Initialize()
            {
                std::shared_ptr<Backend> backend = nullptr;
            #ifdef Q_OS_LINUX
                backend = std::make_shared<LinuxBackend>();
            #elif defined(Q_OS_WIN32)
                backend = std::make_shared<WindowsBackend>();
            ...
            #endif
            }

            не сделаешь.


        1. DistortNeo
          28.11.2018 20:44
          +2

          Нет, не позволяет — обе ветки должны компилироваться.


          1. 0xd34df00d
            28.11.2018 21:01
            +1

            Нет, там всё сложнее. Они не обязаны тайпчекаться, по крайней мере, в тех контекстах, которые зависят от шаблонных параметров.


    1. vanxant
      29.11.2018 02:10

      Вот не надо вот от препроцессора отказываться. Это ещё более замедлит принятие С++ на всяких микроконтроллерах и SoC, где до сих пор пишут на С образца семьдесят лохматого года.


      1. Antervis
        29.11.2018 02:58
        +1

        пишущие на си образца семидесятых годов заведомо не аудитория новых стандартов с++


      1. exception13x
        29.11.2018 10:18

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


        1. Amr
          29.11.2018 13:06
          +1

          Это заблуждение или как говорят, ваши коллеги скорее всего не умеют готовить embedded проекты на С++.
          Стандартная либа в таких проектах обычно не используется, а вот все плюшки языка доступны


        1. antoshkka Автор
          29.11.2018 13:08

          Рекомендую показать вашим знакомым consteval-функции C++.

          В комитете присутствующие embedded разработчики были вне себя от радости. Теперь можно легко заставлять компилятор вычислять что-то только на этапе компиляции, без попадания этого в рантайм.


  1. ilynxy
    28.11.2018 10:31
    +1

    Не могу найти на фотке автора ranges. Где радостный Эрик?! =)


    1. antoshkka Автор
      28.11.2018 10:48

      Сидит почти что в центре фотографии. Но на фото не попал Кейси Картер — второй по величине вкладчик в Ranges :(


      1. kent2spb
        28.11.2018 11:18

        А Рядом с ним Гор Нишанов?


        1. antoshkka Автор
          28.11.2018 11:20

          Ага. Если хотите — могу выложить фотографию в оригинальном разрешении. Там больше лиц видно, и даже меня можно разглядеть в зеркале :)


  1. nikitaevg
    28.11.2018 11:08
    +1

    Меня мучит вопрос, может кто подскажет: в бустовом variant и optional есть поддержка ссылок, в std их нет. Я читал, что это из-за неопределенности оператора присваивания. Но может стоило все-таки пойти по пути буста? Мне лично очень часто нужна опциональная ссылка, да и вариант со ссылкой тоже. Почему приняли именно такое решение, которое (кажется, сильно) ограничивает сферу примененя этих типов?


    1. antoshkka Автор
      28.11.2018 11:17
      +1

      Ссылки напрямую не поддерживаются, но всегда можно написать std::variant от std::reference_wrapper и получить поведение близкое к Boost.

      А проблему вы верно указали — поведение std::varaint<int, int&> при присваиваниях будет определяться внутренним содержимым. Это показалось странноватым комитету, и решили не поощрять подобное и не переусложнять класс variant. Те кому всё же нужно подобное поведение всегда могут воспользоваться reference_wrapper


  1. gbug
    28.11.2018 12:09
    +1

    Может кто-нибудь разъяснить что значит dynamic_cast внутри constexpr-выражения? Как это вообще понимать?


    1. VioletGiraffe
      28.11.2018 12:18
      +1

      А в чём проблема? Известен тип и значение аргумента, можно вычислить результат. Если такое приведение невозможно, результатом будет nullptr.


      1. gbug
        28.11.2018 14:29
        +1

        Тогда получается, что это просто static_cast, который возвращает nullptr в случае неудачи, так?


        1. antoshkka Автор
          28.11.2018 14:31
          +1

          Да. Ну и вам будет проще переносить имеющийся код на constexpr — dynamic_cast будет просто работать, не надо будет их заменять на странные конструкции с std::is_constant_evaluated.


          1. gbug
            28.11.2018 14:39
            +1

            Фух, понял! Благодарствую, а то с утра не отпускало:)

            (Плюсануть не могу, неполноправный.)


    1. antoshkka Автор
      28.11.2018 12:22

      Если мы создаем переменную в constexpr контексте, то компилятор об этой переменной должен всё знать, включая её внутреннее представление и базовые классы.

      И соответственно, раз компилятор о ней всё знает, то он может и отслеживать тип переменной, даже если она передаётся по ссылкам на базовый класс. Ну а раз так, то почему бы не разрешить ему и dynamic_cast делать:

      struct base {
          constexpr virtual ~base() = default;
      };
      
      struct forty_two: public base {
          constexpr int say_42() const { return 42; }
      };
      
      constexpr int try_say(const base& b) {
          forty_two* p = dynamic_cast<forty_two*>(&base);
          if (p) {
              return p->say_42();
          }
      
          return 0;
      }
      
      constexpr void do_something() {
          constexpr forty_two ft{};
          static_assert(try_say(ft) == 42);
      }


      1. gbug
        28.11.2018 14:18
        +1

        Ага, понятнее, спасибо! А в случае, если переменная создана не в constexpr-контексте, тогда и функция перестанет быть constexpr, так?


        1. antoshkka Автор
          28.11.2018 14:29

          Да, всё верно. Функция будет выполняться на рантайме. Или будет ошибка компиляции если попробуете использовать эту функция в том месте, где компилятор требует вычисление на этапе компиляции:

          void do_something() {
              /*constexpr*/ forty_two ft{};
          
              // Следующая строчка не соберётся. Компилятор будет жаловаться,
              // что переменная `ft` не известна на этапе компиляции и он не может
              // выполнить `try_say` как constexpr функцию.
              static_assert(try_say(ft) == 42); 
          }


  1. NeoCode
    28.11.2018 13:03
    +1

    По сути все идет к тому что в каждом компиляторе C++ будет встроенный интерпретатор C++. Интересный путь развития…


    1. antoshkka Автор
      28.11.2018 13:07

      Интересно было бы ещё дать пользователям доступ к этому интерпретатору на рантайме. Чтобы можно было пользовательский ввод интерпретировать как функцию, компилировать и выполнять её.


      1. rkfg
        28.11.2018 14:39

        Это ведь достаточно редко нужно, а так clang, вроде, достаточно модульный, чтобы его библиотеки использовать в своём коде.


      1. exception13x
        28.11.2018 15:49

        Мне кажется, Вы говорите про Common Lisp :)


      1. eao197
        28.11.2018 16:05
        +1

        Можно посмотреть на механизм текстовых mixin-ов из D. Там можно вызвать CTFE функцию (compile-time function evaluation, аналог плюсовых constexpr/consteval), которая возвращает строку. Строка скармливается конструкции mixin. Компилятор берет эту строку как подлежащий разбору и обработке исходный код.

        У такого подхода есть большой плюс. Функции, которые генерят строки для mixin-а, — это обычные функции и их можно обычным образом отлаживать и покрывать тестами. Поэтому написать генератор кода для какого-то своего DSL не сложно.

        Но есть и проблема, как говорят D-шники: если в mixin отдали сгенерированный в compile-time текстовый фрагмент, например, такого вида:

        class Generated {
          void f() {...}
          void g() {...}
        }
        а потом в программе написали:
        auto obj = new Generated;
        obj.g();

        то войти отладчиком внутрь Generated.d() пока нельзя. Но это особенность текущей реализации D-шных компиляторов, они не генерируют отладочную информацию для таких случаев.

        В C++ часть того, что можно делать на текстовых mixin-ах из D, может стать доступной через метаклассы. Но, наверное, не все.


      1. RPG18
        28.11.2018 17:11

        Не откроет ли это ящик Пандоры?


        1. NeoCode
          28.11.2018 19:59

          Всенепременно откроет (если уже не открыли, с тьюринг-полными шаблонами). Но тем
          интереснее:)


  1. alexgpg
    28.11.2018 13:58
    +1

    А почему Networking отложили?


    1. antoshkka Автор
      28.11.2018 14:02

      Возникли подозрения, что дизайн можно улучшить, используя последние новинки C++20 (в основном концепты, и немного ranges).


      1. mapron
        28.11.2018 19:55

        Так автор Networking вроде на cppcon об этом прямо говорил, что «ребейзить» надо.


        1. antoshkka Автор
          28.11.2018 20:00

          О! А можно ссылочку на видео, а то я найти не могу :(


          1. mapron
            28.11.2018 20:09

            www.youtube.com/watch?v=hdRpCo94_C4 (да, это не автор TS)
            вот это вроде, долго чет искал) Таймкод с пруфом про «надо ребейзить» не подскажу. Если я ошибся, то может и не это видео вовсе. Извините в случае чего.


  1. eao197
    28.11.2018 14:43

    А про алгебраические типы данных и паттерн-матчинг что-нибудь известно? Вроде как перед этой встречей появилось несколько конкурирующих предложений на эту тему.


    1. antoshkka Автор
      28.11.2018 15:23

      До их рассмотрения дело не дошло. Зато успели немного пообсуждать монадические интерфейсы для std::optional.


      1. eao197
        28.11.2018 15:27

        До их рассмотрения дело не дошло.
        Жаль. Видимо, придется ждать C++23 или даже C++26.
        Зато успели немного пообсуждать монадические интерфейсы для std::optional.
        Дурное дело не хитрое.

        Шутка :)


      1. nikitaevg
        28.11.2018 17:38

        Можете вкратце описать результаты обсуждения? Было бы очень интересно увидеть когда-нибудь что-то такое.


        1. antoshkka Автор
          28.11.2018 18:24

          Обсуждали предложение P0798. В отсновном выбирали имя для функции map/transform и определялись с требованиями к аргументам данной функции. В C++20 попасть скорее всего не успеет.


      1. 0xd34df00d
        28.11.2018 21:06

        Зачем только для std::optional, если можно просто корутины доработать и выразить через них (монады для конкретно optional у меня уже есть, а вот для Either я не осилил сделать, там байнд для левого случая нетривиальный).


  1. eao197
    28.11.2018 15:27

    Del


  1. Antervis
    28.11.2018 15:46

    а можно поподробнее про

    // Следующие две строчки могут пагубно повлиять на рассудок:
    assert(c_auto[4] == 11); // не константно
    assert(c_auto[5] == 11); // константно
    

    из примера про is_constant_evaluated? Почему так?

    Может ли к с++20 constexpr приехать в математические функции стандартной библиотеки? Просто глупо получается, что после всех притянутых в стандарт constexpr-фич попытка буквально «что-нибудь посчитать на этапе компиляции» спотыкается об какой-нибудь std::sin


    1. ZaMaZaN4iK
      28.11.2018 15:57

      1. antoshkka Автор
        28.11.2018 16:21

        Математические функции уже почти сделали constexpr, я надеюсь что успеется к C++20. LEWG одобрила бумагу https://wg21.link/P0533, осталось пройти всего одну группу.

        Основная проблема — это имплементация. У GCC всё хорошо в этом месте, а вот Clang не может воспользоваться библиотекой от GCC для математических вычислений на этапе компиляции — лицензия не позволяет. А написать подобную библиотеку самим — это огромные трудозатраты (приблизительно сотня или тысяча человеколет).

        Так что когда примут в стандарт, некоторые компиляторы часть функций не смогут сделать constexpr в течение длительного времени.


    1. antoshkka Автор
      28.11.2018 16:11

      Про странный пример… Всё сводится к вычислению вот этих двух строчек с переменной `in` известной только на рантайме:

          const int v_runtime0 = __builtin_is_constant_evaluated() ? in : 11;
          const int v_runtime1 = __builtin_is_constant_evaluated() ? 11 : in;


      Так вот, если для v_runtime0 функция is_constant_evaluated вернёт true, то получится что v_runtime0 надо подсчитать константно с помощью рантайм переменной. Это что-то невозможное, поэтому тут возвращается false.

      Для v_runtime1 если функция is_constant_evaluated вернёт true, то никаких противоречий нет и можно подсчитать константно.

      Как справедливо заметили в чатике t.me/ProCxx, решать надо как в загадках про лжеца: «могло быть в первом ответ y? нет, потому что было бы противоречие».


  1. mkshma
    28.11.2018 16:19
    +1

    К C++20 многие (и я в их числе) хотят увидеть в стандарте контейнеры, которыми можно пользоваться на этапе компиляции.

    А можно юзкейсов немного? А то я пока даже в принципе не понимаю зачем нужны constexpr. constexpr контейнеры же для меня вообще rocket-science какой-то.


    1. ZaMaZaN4iK
      28.11.2018 16:27

      Пример простой — рефлексия


    1. antoshkka Автор
      28.11.2018 16:45

      Самый ожидаемый мной контейнер — constexpr std::string. За счёт того, что компилятор сможет создавать такую строчку на этапе компиляции, иницилизация в следующем коде перестанет быть динамической и станет статической:

      void foo() {
          static const std::string date_time_fmt = "DATE: YYYY MM DD TIME: BLA-BLA";
      }
      

      Другими словами, вся инициализация будет происходить на этапе компиляции, и при первом заходе в функцию не будет залочиваться мьютекс (или ещё как-то потоко-безопасно инициализироваться статическая переменная), не будет динамически выделяться память…

      Весь код с статическими/глобальными строковыми переменными станет работать немного быстрее.

      Другой практический пример — это constexpr std::unordered_map. Можно будет делать подобие switch по строкам.

      Любителям метапрограммирования с constexpr std::vector откроются новые возможности. Так например подобное нечитаемое безобразие просто не надо будет писать, так как можно будет обойтись std::vector и алгоритмами из стандартной библиотеки. Метапрограмный код получится читаемый, а не тот что мы имеем в C++14/17.

      Ну и наконец — без constexpr контейнеров не сделать рефлексию, а её очень хотят успеть к C++23.


      1. ABBAPOH
        28.11.2018 18:49

        Любителям метапрограммирования с constexpr std::vector откроются новые возможности. Так например подобное нечитаемое безобразие просто не надо будет писать, так как можно будет обойтись std::vector и алгоритмами из стандартной библиотеки. Метапрограмный код получится читаемый, а не тот что мы имеем в C++14/17.


        Не является ли данный пример типичным местом применения для gsl::span?
        Кстати, как дела у std::array_view, всё заглохло?
        constexpr строки и вектора это оч хорошо (вью же не сложишь), но на моей практике многое делается уже c одним gsl::span (хотя я знаю у себя место где constexpr вектор бы упростил код)

        Upd: а, там массив возвращается; ну да, вектор полезен был бы


      1. bibmaster
        29.11.2018 09:45

        А чем не вариант для константных строк использовать string_view? Если она инициализируется литералом, время жизни обеспечено. Можно даже отнаследовать какой нибудь literal_view с constexpr конструктором из массива char.


        1. antoshkka Автор
          29.11.2018 10:17

          Для константных — самое то. Но вот выше люди коментируют, что хотят макросами имена функций и переменных генерировать. Для того чтобы это можно было делать через рефлексию, а не макросы, нужен constexpr string.


    1. ABBAPOH
      28.11.2018 19:23

      constexpr нужны для манипуляциями над данными в RO памяти, которых в программах может быть достаточно много. Например, у нас есть массив, данные в котором мы ищем по индексу. Как не нафакапить при заполнении массива и не промахнуться с индексом? Очень просто, написать constexpr функцию, проверяющую валидность массива и вызвать её из static_assert.

      А теперь допустим мы ходим искать в этом массиве не по индексу, а по содержимому.
      Сделаем constexpr хэшмапу и будем искать за (примерно) константное время. Впрочем, этот велосипед был скорее на поиграться с возможностями нового с++; в мире розовых поней я лучше подожду constexpr std::unordered_map.


  1. sborisov
    28.11.2018 16:30

    Всё очень круто! Но будет ли помещаться С++20 в голову разработчику?
    Нужен новый Майерс, раз уж старый Майерс завязал с объяснениями хитростей С++!


    1. ZaMaZaN4iK
      28.11.2018 16:36

      Для этого даже создали отдельную подгруппу в комитете :-) Если у Вас есть идеи, как можно помочь — то добро пожаловать :)


    1. eao197
      28.11.2018 18:28
      +1

      Но будет ли помещаться С++20 в голову разработчику?
      В мою и C++98 не помещался. Но, как показала практика, если ты не разрабатываешь компилятор C++ или стандартную библиотеку для C++, то знать _весь_ C++ и не нужно.


      1. sborisov
        29.11.2018 11:38

        Уверяю вас, вы не одиноки!


    1. antoshkka Автор
      28.11.2018 18:49
      +2

      Но будет ли помещаться С++20 в голову разработчику?


      Большинство стандартных библиотек современных языков программирования не помещаются в голову разработчику: Java, C#, C++, Python…

      Я немного не следил за событиями: в других языках тоже жалуются?


  1. antoshkka Автор
    28.11.2018 16:44

    del


  1. Amomum
    28.11.2018 19:08

    А как поживает constexpr с восклицательным знаком?


    1. domix32
      28.11.2018 19:13
      +1

      Это же упомянутый consteval? Или что-то ещё?


      1. Amomum
        28.11.2018 19:17
        +2

        Да, проморгал. Спасибо!
        Слава богу, решили выпилить этот восклицательный знак, фуф.


        1. mapron
          28.11.2018 19:58

          Ну там и доллар из метаклассов и рефлексии выпилили.


          1. Amomum
            28.11.2018 21:33

            И это проморгал :( Ссылку можно?


            1. mapron
              28.11.2018 22:34

              По метаклассам вот последняя ревизия:
              www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0707r3.pdf
              по рефлексии
              www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0194r6.html
              изменение с 8 по 9 ревизии посмотрите


              1. Amomum
                28.11.2018 22:43

                Спасибо!

                old: $class M 
                new: constexpr void M(meta::type target, const meta::type source)


                Ммда, ну, поживем-увидим.


                1. mapron
                  28.11.2018 23:10

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


  1. mapron
    28.11.2018 20:01
    +2

    Интересно было бы услышать тех, кто 2D графику в опросе выбрал — как вы будете это использовать, для чего? Использовать стандартную библиотеку без какого-либо графического фреймворка?


  1. antoshkka Автор
    28.11.2018 20:25

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


    1. mapron
      28.11.2018 20:40

      Вы мимо, но спасибо)

      отрисовать картинку со статистикой и отдать её пользователю

      Ну пользователю-то картинку и пожать придется? я почитал
      www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0267r7.pdf
      там же рендеринг только.
      Не будут же туда еще видео кодеки пихать)


      1. antoshkka Автор
        28.11.2018 21:45

        Там есть сохранение в формате изображений (PNG и JPEG точно были).


        1. mapron
          28.11.2018 22:29

          Да, я виноват, просмотрел, 13.9 раздел, если кому интересно.
          В такой постановке, согласен, может быть полезно для минималистичного взаимодействия. Все равно меня немного напрягает «внешняя зависимость» в виде PNG кодеков в стандартной библиотеке, и как это все будет специфицировано (с учетом того что периодически всплывают уязвимости в libpng той же).


          1. antoshkka Автор
            28.11.2018 22:43

            В юникоде, стандартной библиотеке и demanglingе тоже уязвимости всплавают. Пока всё норм.


    1. domix32
      28.11.2018 20:41
      +2

      то есть подтянуть внутрь стандартной библиотеки libpng/libbmp/libsvg? Или в каком виде отрисовывать? Почему не скомпилировать это wasm и рисовать в канвас из локального фреймбуффера если это веб?


      1. ABBAPOH
        28.11.2018 21:00

        То есть Cairo в стандарте не смущает (а это и есть пропозал), а libpng смущает?)


        1. snizovtsev
          29.11.2018 00:08
          +2

          Смущает. Все серьезные приложения (вроде браузеров) уже переехали на Skia, а тут стандартизацию Cairo ещё только обсуждают.


        1. domix32
          29.11.2018 01:49

          Смущает. Хотя наверное было бы неплохо иметь некоторый кроссплатформенный интерфейс для кодеров/декодеров изображений и аудио до кучи. Но это не раст с его типажами, поэтому довольно сомнительно все это.


          1. antoshkka Автор
            29.11.2018 08:38

            А как в раст подобные типажи помогут?


            1. domix32
              29.11.2018 23:25

              В раст можно прокинуть некоторый интерфейс графики который реализовать отдельными крейтами. Но тут же возникает зачем оно в стандартной библиотеке. Да и боли с рисованием там тоже особо нет.


    1. DistortNeo
      28.11.2018 20:50
      +2

      А зачем это в стандарной библиотеке?


      1. antoshkka Автор
        28.11.2018 21:47
        -1

        Чтобы можно было пользоваться, а не страдать. Networking, std::thread, Filesystem служат той же цели (впрочем как и вся стандартная библиотека).


        1. DistortNeo
          28.11.2018 21:55
          +2

          С++ нужна не раздутая стандартная библиотека, а нормальный репозиторий для всего этого хозяйства.


          1. antoshkka Автор
            28.11.2018 22:26

            C++ в первую очередь нужна функциональная стандартная библиотека.


            1. mapron
              28.11.2018 22:31

              Согласен, но может это хотя бы сделают на откуп вендорам, как было со стандартизацией больших интов и GC? просто например какой-нибудь вендор под embedded может и не захотеть реализовать стандарт под свою железку. (хотя чего я, как будто бы сегодня их заставляют реализовывать весь стандарт).


              1. antoshkka Автор
                28.11.2018 22:41

                Сейчас наоборот идёт движение в сторону того, чтобы явно разметить в стандартной библиотеке embedded/freestanding части. Тоесть выделить некое подмножество стандартной библиотеки, которое работает на любой платформе, даже на такой где нет оперативной памяти, файловой системы и проч.


                1. mapron
                  28.11.2018 23:12

                  Ееее! Это очень крутое движение, рад был про это слышать (удивительно как я такое пропустил).


        1. snizovtsev
          29.11.2018 00:06
          +2

          Networking, std::thread, Filesystem

          Это всё следствия бетонирования POSIX. А графический стек везде разный и меняется постоянно, чтобы соответвовать новым ускорителям и железкам. Ваша библиотека морально устареет раньше, чем её успеют стандартизировать.


          1. antoshkka Автор
            29.11.2018 10:27

            Я не специалист в 2D графике, но насколько мне известно основные принципы отрисовки за последние 30 лет не менялись. Применяешь к холсту примитивы, говоришь отрисовать, готово.

            Поправьте меня если я не прав.


  1. Amomum
    28.11.2018 22:46
    +2

    А как поживает P0631R0? Появится ли наконец-то в С++20 стандартная константа для числа Пи? Или так и будем 4*atan(1)?


  1. mapron
    28.11.2018 23:32

    Что-то мне не очень понятна ситуация c [[visible]]:
    www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0276r0.html
    и
    www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1283r0.html

    Пусть у нас в хедер файле

    [[shared]] void library_foo();
    

    Когда мы его подключаем из реализации, считается, что мы делаем экспорт.
    Когда включаем это объявление, и реализации нет — считаем что импортируем из библиотеки.
    Теперь вопрос, а если у нас этот же хедер используется для статической библиотеки? тут уже без макроса не обойтись, верно? Иначе использующий API код не сможет определить, что ему там вставлять, обычную слабую ссылку или импорт (в MSVC там будут отличаться имена символов ж).


    1. Antervis
      29.11.2018 03:23

      отдельные аттрибуты для импорта/экспорта — чисто msvc-шная проблема и если они её решат, то лучше будет всем.


      1. mapron
        29.11.2018 12:04

        Дело не в отдельный аттрибутах (я про них не упоминал). Уверен, разработчики смогут справиться. Речь о том что разные имена в ABI, и это не покрыть фичами языка (либо создавать новый ABI которым никто не будет пользоваться).


  1. vanxant
    29.11.2018 02:17

    Язык без «изкоробочной» поддержки UTF-8 в 2020 году это провал, ребята.
    Если комитет этого не понимает, то анонсированного выше в комментариях С++35 просто не будет.


    1. mapron
      29.11.2018 13:17

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

      Посмотрите на Boost.Text, может вам понравится:
      www.youtube.com/watch?v=944GjKxwMBo

      p.s. я даже не буду комментировать «провал» языка который живет 30 лет и загибаться не планирует.


      1. vanxant
        29.11.2018 17:14
        +1

        Чувствую себя агрессивным проповедником в чужой церкви, но блин, коллеги, давайте смотреть правде в лицо.
        Что у нас было 20 лет назад? Был STL, которым никто не пользовался, даже самыми базовыми вещами. Все юзали те же строки и массивы или в стиле С, или CString/CArray, или свои велосипеды. При этом CString уже поддерживал (тогдашний) юникод. Однако С++ являлся топовым универсальным языком, на котором писали всё — от системных утилит до фронтенда.
        Прошло 20 лет, строки С++ всё ещё не поддерживают юникод.
        Ну ок, фронтенд потерян безвозвратно. Весь бизнес-приклад давно переехал на java/.net. Как и 90% кода операционных систем. Бэкенд, всякие веб-сервисы, отжали пых и руби. Новые системные тулзы пишут на расте или го, не на плюсах. Наука со своим матаном переехала на питон. Геймдев ещё держится, но с этими вашими смартфонами и там уже не всё гладко.
        Может С++ загибаться и не планирует, но по факту он уже сегодня воспринимается ближе к фортрану или коболу, чем к промышленному языку.
        Простите, не хотел никого обидеть.


        1. antoshkka Автор
          29.11.2018 17:31
          +4

          Хм… я пишу это сообщение из браузера написанного на C++, используя операционку у которой пользовательские библиотеки почти все на C++, собранную компилятором написанном на C++… разработчики которого играют в игры, написанные на C++ :)

          … при этом работаю в фирме, где «бизнес приклад» написан на C++, и даже веб сервисы написаны на C++.

          За всю науку говорить не могу, но в CERN бозон хиггса искали используя плюсы (и Boost), в ИММ РАН физические задачи решают на C/C++/Fortran… да и в МГУ тоже физики используют C++.

          Что-то в ваших показаниях не сходится.


        1. eao197
          29.11.2018 17:51

          Был STL, которым никто не пользовался, даже самыми базовыми вещами.
          Вы вот как-то с ходу начали оперировать ошибочными постулатами. Я, например, один из тех, кто начал использовать STL еще до принятия C++98. Тогда по рукам ходила реализация STL от Rogue Wave, кажется, которую можно было скотчем и спичками прицепить к Watcom C++, Borland C++. А в 1998-ом в Visual Studio 6.0 STL уже был из коробки, хотя и не стандартный еще.

          Так что вы уже со своим тезисом «никто не пользовался» не правы. Ну и дальше, если копнуть, везде такая же история.


          1. vanxant
            29.11.2018 18:05

            Ребят, да я про тенденцию говорю. Тогда на плюсах писали реально всё, из конкурентов был или чистый Си или Паскаль/Дельфи.
            Сейчас мы ниши перечисляем. Вот мол у автора статьи ОСь и браузер написаны на плюсах. А у меня ось на джаве, а браузер потихоньку на раст переписывают.
            Если бы лямбды, auto и нормальный for появились на 10 лет раньше, этого бы не было.


            1. eao197
              29.11.2018 18:14

              А у меня ось на джаве
              Это какая?
              Если бы лямбды, auto и нормальный for появились на 10 лет раньше, этого бы не было.
              Да ладно, устойчивая тенденция миграции с C++ на Java началась где-то в 2000-ом или 2001-ом. К 2004-ому она уже была вполне себе четкой. И Java тогдашняя по выразительности с C++98 не могла соревноваться.

              Зато она была безопасной, со сборкой мусора, большим JDK. И даже умудрялась не так уж и сильно тормозить на тогдашней технике.

              За прошедшие 15 лет C++ уже вытеснили из тех ниш, где его выгодно было заменить на Java, C#, Scala и пр. Но там, где он остался и применяется сейчас только Rust и, отчасти, Go может что-то предложить. Да и тому же Rust-у еще экосистему свою вырастить нужно. А то что ни растоман, то и жалоба, что Qt у них нет.


              1. vanxant
                29.11.2018 18:38

                Это какая?

                Ведроид жи ну. Да-да, я знаю, что там внутре у ней неонка, в смысле линукс, но он тоже не на плюсах написан.


                1. antoshkka Автор
                  29.11.2018 18:41
                  +2

                  У Андроида практически весь userspace написан на C++, включая линкер.


                1. eao197
                  29.11.2018 19:34

                  Ну так не на Java же OS написана. Пока. Вроде как Google хочет со временем на Фуксию перевести, которая уже на плюсах пишется.


                  1. vanxant
                    29.11.2018 19:41
                    +1

                    ОС это не только и не столько ядро. Это библиотеки, утилиты, планировщики, рюшечки, окошечки и прочие пакетные менеджеры. Посмотрите на зоопарк дистрибутивов Линукса — перевести прод с условной федоры на убунту не сильно проще, чем с винды (из-за чего всякие докеры и появились).
                    Возврат гугла к плюсам обусловлен, в первую очередь, тем, что у самой java проблем выше крыши, причём как технических, так и юридических и организационных. Ну и да, здесь надо похвалить комитет, плюсы сейчас развиваются действительно поживее, чем java.


                    1. eao197
                      29.11.2018 19:44

                      Это библиотеки, утилиты, планировщики
                      И вот это все на C или C++.
                      рюшечки, окошечки и прочие пакетные менеджеры
                      А это уже относится к ОС, если под ОС понимать что-то вроде Windows. А вот в том же Linux-е есть сама ОС и есть Desktop Environment. Вот окошечки-рюшечки — это про Desktop Environment, а не про ОС.


              1. antoshkka Автор
                29.11.2018 18:45

                Слышал что уже длительное время идёт обратная миграция. Процессоры почти перестали расти в тактовой частоте и в основном растут в количестве ядер. Ну и тут grabage collector начинает играть злую шутку: если у вас 1 ядро, и GC отрабатывает за 1мс, то вы теряете 1мс процессорного времени; если у вас 16 ядер, и GC отрабатывает за 1мс, то вы теряете 16мс процессорного времени. Альтернативные подходы к GC обладают аналогичными недостатками.


                1. eao197
                  29.11.2018 19:36

                  Слышал что уже длительное время идёт обратная миграция.
                  Да тут сложно оценки сделать. С одной стороны — да, есть прецеденты, когда с Java переходят на C++ (или используют в Java код на плюсах через JNI). С другой стороны, на Java и C# делают тот же самый HFT, где плюсам самое место (и где они хорошо себя чувствуют).


                  1. domix32
                    29.11.2018 23:37

                    А можно ткнуть пальцем, где HFT на шарпах/java пишут? Я пониаю когда околовычислительне всякие микросервисы, графики рисовать, отчеты пилить, но вот чтобы прям непосрдественно общение трейдеров — не сышал.


                    1. eao197
                      29.11.2018 23:58

                      Наверное, самый известный — это Lmax со своим Disruptor-ом.

                      Несколько лет назад здесь, на Хабре было интервью с Романом Елизаровым, он там рассказывал про разработки трейдинговой системы на Java. Там же есть ссылка на OpenHFT.

                      Про разработку на C# в обсуждении на RSDN-е кто-то рассказывал (отсюда и далее вниз по ветке).


            1. Antervis
              29.11.2018 18:58
              +1

              давайте перефразируем: раньше выбора не было, а сейчас он появился. Раньше железо не позволяло лишний раз писать на джаве/диезе/питоне, а сейчас позволяет. То, что появилась достойная альтернатива в виде раста — хорошо, но едва ли в ближайшем будущем все забросят свои кодобазы и сбегут на него. У плюсов есть старые детские проблемы, и это не значит что их не надо (или нельзя) поправить


              1. vanxant
                29.11.2018 19:20

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


                1. antoshkka Автор
                  29.11.2018 19:24
                  +1

                  Комитет не спорит на тему «надо ли», комитет обсуждает как это сделать правильно. Если вы знаете как это делать правильно — то пишите proposal, вас с радостью выслушают.

                  P.S.: А передёргивать слова некрасиво, я такого не говорил.


                  1. vanxant
                    29.11.2018 19:28
                    -1

                    (Пример про ИММ РАН разве не вы предложили?)


                    1. antoshkka Автор
                      29.11.2018 20:20
                      +1

                      Примеры передёргивания:
                      1) Java иногда используются для студенческих курсовых. Жаль, ведь получается что этот язык — лишь удел недоучек.
                      2) Андроид использует Java. Не спроста vanxant утверждает что данная ОС — удел разработчиков недоучек.

                      Тут приличное общество, давайте не будем опускаться в дискуссиях до подобных приёмов.


                1. Antervis
                  29.11.2018 19:25

                  предложите навскидку zero-overhead юникод библиотеку


                  1. vanxant
                    29.11.2018 19:35
                    +1

                    А нету таких. Переход на юникод это боль и страдания. Питон страдал несколько лет, php до сих пор страдает с mbstring и func_overload, и так далее. Но вариантов нет, мир уже чуть больше, чем горстка юзеров в англоязычных странах.
                    Комитет на то и нужен, чтобы изучить ошибки других, сжать тестикулы в кулак, принять решение и добровольно-принудительно перейти всем сообществом. А не как у нас в плюсах принято, что в языке несколько видов строк, несколько видов «умных» указателей, а к четырём одновременно существующим видам обработки ошибок предлагается добавить ещё столько же. Берёшь либу и не знаешь, что от неё ожидать.
                    Есть, в конце концов, буст, где можно обкатать потенциальных кандидатов «в живой природе» до их стандартизации.


                    1. domix32
                      29.11.2018 23:39

                      А можно ссылку на историю о страданиях питона? Я думал его изначально с поддержкой делали.


                    1. mapron
                      30.11.2018 00:25

                      «Берёшь либу и не знаешь, что от неё ожидать»
                      Пока для меня, основная боль как разработчика, это не то что в С++ нет какой-то там поддержки utf-8, а то что сторонние кроссплатформенные C библиотеки просто используют fopen/stat и т.п. которые разумеется на Win работают, но без поддержки юникода.
                      — ffmpeg/vidstab
                      — opencv — весь файловый api
                      — glog
                      — dlib
                      (первое что за минуту в голову пришло, тысячи их)
                      Да, патчи-то наложить недолго, но е-ёмое, не понимаю я разработчиков библиотек, под винду эти функции существуют два десятка лет, вы делаете «кросплатформенность» и забиваете на поддержку юникода в FS? что с вами не так?
                      MS, сделайте уже поддержку setlocale(«utf-8»), чтобы fopen работал как везде, это не лечится)


        1. domix32
          29.11.2018 23:32

          А можно показать такие системы у которых 90% кода написаны на .net/java?


  1. Panzerschrek
    29.11.2018 08:39
    +2

    Раньше у нас были char, signed char, unsigned char, wchar_t, int8_t, uint8_t, теперь ещё char8_t появился. Как-то уж слишком много сущностей, полоснуть бы бритвой Оккама по ним.


    1. Anton3
      29.11.2018 21:25

      char = текст ASCII
      chat8_t = code unit из UTF-8
      int8_t, uint8_t = целые числа
      std::byte = неизвестные данные (не текст и не числа)
      wchar_t = системный тип символа (привет, ужасы кодировок Windows)
      signed char, unsigned char = что угодно в устаревшем коде; стоило бы выпилить


  1. dm_frox
    29.11.2018 12:57

    Интересно, когда все эти радости начнут поддерживать популярные компиляторы. Судя по поддержке С++11/14/17 как раз где-то к 2023 году. А до этого останется только обсуждать все это в блогах. И ведь еще дожить надо.


    1. mapron
      29.11.2018 13:01
      +2

      Вы неправы. Начиная с С++14, поддержка максимум на год задерживалась. Другое дело, что если концепты вы можете начать использовать сразу после появления их поддержки в тулчейне, то вот с модулями не все так просто) минимум ждать поддержки и в системах сборки, а максимум — во всех используемых вами библиотеках.
      Ну вот сейчас 2018 год, С++17 полностью (по крайней мере на словах) 3 популярных компилятора поддерживают. У нас все проекты собираются с флагами 17 стандарта.

      Благодаря регулярным и предсказуемым релизам, разработчики компиляторов могут как раз быстрее реализовывать фичи. Т.е. в 2019 заморозят набор фич, и к 20 году большая часть в том или ином виде будет реализована со спец флагами в компиляторах. Для концептов, контрактов и модулей, кстати, флажки или экспериментальные ветки уже есть.


      1. RamzesXI
        29.11.2018 15:50

        С++17 полностью (по крайней мере на словах) 3 популярных компилятора поддерживают.

        Как там поживает <memory_resource>? А < execution >?


        1. mapron
          29.11.2018 16:11

          А вот тут речь уже о том что фичи стандартной библиотки тянутся медленнее)
          Компилятор — «да! да здравствует новый стандарт!», его реализация STL — «подождите, пожалуйста помедленнее, я запсваю» =)
          Если не брать штуки по constexpr — то большая часть мажорных нововведений как раз по части компилятора, я думаю с ними проблем не возникнет.

          в любом случае, согласитесь, что 5% отдельных фич, с которыми проблемы, это не та вещь про которую можно ныть «ой беда, 10 лет теперь стандарт реализовывать будут».