company_banner

C++20 и Modules, Networking, Coroutines, Ranges, Graphics. Итоги встречи в Сан-Диего

    До 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 в Новосибирске.

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

    В каких нововведених C++ вы заинтересованы

    Яндекс

    754,00

    Как мы делаем Яндекс

    Поделиться публикацией
    Комментарии 216
      +4
      Есть новости, когда планируется отказаться от хэдеров и препроцессора?
        +16
        Нужно чтобы все проекты переехали на модули, тогда и можно будет отказываться (другими словами — не раньше C++35)
          0

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

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

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

                0

                antoshkka, Ваш комментарий мы услышим или нет?

                  0
                  Коментарий на «придумать то, чего в принципе не придумано, но кому-то хорошо было бы иметь»?

                  ОК, когда-нибудь попробую реализовать в Boost.
                    0

                    Относительно Coroutines. Не приходила мысль сделать их в стиле мувиклипов как в ActionScript c теме же названиями методов .gotoAndPlay, .gotoAndStop и т.д Ещё и визуализировать в 2D Graphics опять же в стиле CreateJS (canvas или лучше сразу портировать для svg) с иерархией аля DisplayObject — с localToGlobal для локальных видов. Частично это всё довольно старые идеи, взятые ещё от команды as3commons. Некому поднять и реализовать.

                      0
                      Пишите детальное предложение, кажется что в ваши идеи стоит показать комитету.
                        0

                        Я попозже напишу вам в личку. Торопиться мне некуда.

          +2
          Без макросов некоторые вещи не делаются, когда будут делаться, тогда и можно отказываться. Вещи, связанные с удобным для программиста генерированием повторяющегося исходного кода.
            +3
            Интересно, а идей улучшить препроцессор вместо того что бы хаить макросы не возникало?
              0
              А как именно вы предлагаете его улучшить?
                +1

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

                  0
                  А расскажите поподробнее, как вы видите подобные макросы в C++?
                      +3
                      вы пропустили важную деталь:
                      А расскажите поподробнее, как вы видите подобные макросы в C++?

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

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

                          +1
                          ок, сделать допустим можно. Нужно ли? Для большинства случаев шаблонов более чем достаточно, а с появлением концептов не хуже ни синтаксис, ни гарантии. То, что на шаблонах сейчас сделать сложно или нельзя, будет рефлексия. Для случаев, связанных с условной компиляцией (дебажная информация, юнит-тесты и пр.) эти гигиенические макросы всё равно будут полагаться на сырые макросы флагов компиляции. Для остального (документация, например) требуется не столько поддержка от компилятора, сколько от системы сборки.
                            0
                            То что я выше посмотрел по ссылке, не рефлексию больше напоминает, а generator expressions, которые позволяют ast менять, очень для метаклассов будут полезны. Но это точно не C++23, как Саттер сказал. Может быть какой-то TS к 26 году разве что.
                        +1
                        Это всё опять же «такое себе решение».Нужно элементарное: больше базового синтаксиса на этапе компиляции тогда и макросы станут не нужны.

                        Вот, например, я хочу написать один шаблон с большим количеством кода, но обрабатывающий либо 1 элемент без списка либо множество элементов из списка и функция обхода элементов списка сама по себе сложная. Так вот макросом или внутренними директивами компилятора я могу не плодить адовую копипасту, а вот на C++ даже с шаблонами и последним стандартом до сих пор не могу, точнее могу могу но костыли, вроде, sfinae не выглядят решением ибо это костыли, ужасные костыли, а я хочу писать, примерно так:
                        <typename T>
                        ... some_func(..., T x, ...)
                        ...
                        if (exist(x.getList))
                        {
                        ... код который даже не скомпилируется без метода getList у типа T
                        }
                        ...
                        ...
                        

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

                        P.S. в идеале хотелось бы даже шаблон не создавать, но это уже совсем мечты.
                          +2
                          Так уже можно:
                          template <class T>
                          concept Listable = requires(T x) {
                               x.getList();
                          };
                          
                          <typename T>
                          ... some_func(..., T x, ...)
                          ...
                          if constexpr(Listable<T>)
                          {
                          ... код который даже не скомпилируется без метода getList у типа T
                          }
                          ...
                          ...
                          
                            +1
                            О, через concept уже лучше и не столь вырвиглазно, благодарю, жаль пока не завезли много где, да и опять же требуется писать много дополнительного кода, как с sfinae. А теперь смотрим на элегантные средства некоторых компиляторов (__if_exists/__if_not_exists Statement) и плачем поскольку средства очевидные, не требуют лишнего кода, работают везде, а не только в шаблонах, очень давно реализованы и это в чистом виде реализуемо как синтаксический сахар :'(

                            // the__if_exists_statement.cpp  
                            // compile with: /EHsc  
                            #include <iostream>  
                              
                            template<typename T>  
                            class X : public T {  
                            public:  
                               void Dump() {  
                                  std::cout << "In X<T>::Dump()" << std::endl;  
                              
                                  __if_exists(T::Dump) {  
                                     T::Dump();  
                                  }  
                              
                                  __if_not_exists(T::Dump) {  
                                     std::cout << "T::Dump does not exist" << std::endl;  
                                  }  
                               }     
                            };  
                              
                            class A {  
                            public:  
                               void Dump() {  
                                  std::cout << "In A::Dump()" << std::endl;  
                               }  
                            };  
                              
                            class B {};  
                              
                            bool g_bFlag = true;  
                              
                            class C {  
                            public:  
                               void f(int);  
                               void f(double);  
                            };  
                              
                            int main() {   
                               X<A> x1;  
                               X<B> x2;  
                              
                               x1.Dump();  
                               x2.Dump();  
                              
                               __if_exists(::g_bFlag) {  
                                  std::cout << "g_bFlag = " << g_bFlag << std::endl;  
                               }  
                              
                               __if_exists(C::f) {  
                                  std::cout << "C::f exists" << std::endl;  
                               }  
                              
                               return 0;  
                            }  
                            

                            Вот именно такое я хочу в стандарте, но даже в 20 этого не будет. Такую замену макросов хочется ^_^
                              +1
                              Всё в ваших руках! Пишите предложение на подобный функционал, с формальностями поможем.
                                0
                                Идея MS хорошая, но недостаточно гибкая: она проверяет только наличие соответствующего идентификатора, но не его свойства, например, различные перегрузки.

                                А вот чего не хватает концептам, так это ключевого слова `implements` (как в Java/C#), чтобы контроль можно было осуществлять при определении сущности, а не при её использовании.
                                  +2
                                  важно как правило не то, есть ли Foo::bar, а есть ли метод Foo::bar, принимающий Args… и возвращающий T
                    0
                    Вещи, связанные с удобным для программиста генерированием повторяющегося исходного кода.

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

                      0
                      Регулярное выражение?
                        0
                        А как их можно макросами реализовать?

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

                          0
                          А как их можно макросами реализовать?
                          Плюсовыми — никак. А вот с макросами вроде 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.
                          0
                          Какой-нибудь кейс когда проще написать макрос нежели шаблон/функцию для регулярки?
                          0
                          if( error ) return error;
                          и прочие модификации control-flow?
                          Конкатенация строк в названиях переменных?
                            0
                            Не вижу в этом ничего хорошего. Код пишется один раз, зато читается постоянно. Упрощение написания кода ценой усложнения его чтения и отладки — это выстрел в ногу.
                              0
                              Вы просили пример — я его привел :) Я не говорю, что это хорошо, но на шаблонах и лямбдах так не сделать.
                            0

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


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

                              0
                              Можете привести пример кода, который невозможно сгенерировать с помощью шаблонов и 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
                                0
                                Спасибо, хороший пример, что отсутствие рефлексии в C++ — это плохо. Но альтернатива с variadic templates и string literals таки возможна:
                                habr.com/post/243581
                                  0
                                  По ссылке не альтернатива, а тонны нечитаемого кода. Минусы у макросов в том что они трудно поддерживаемы и очень неудобно их отлаживать если их использовать как генераторы кода, но если их использовать только для простых вещей, например банальная генерация пары public get/set и private члена, то их, к сожалению, просто нечем заменить в С++, вообще нечем.
                                0
                                А какие-нибудь замены макросам __FILE__, __LINE__ уже придумали?
                            +3
                            От препроцессора отказаться невозможно в принципе, т.к. без условной компиляции не обойтись. Но я бы хотел, чтобы действие директив препроцессора ограничивалось только одним файлом. Именно файлом, а не translation unit.

                              0
                              А constexpr (в С++17) разве не позволяет организовывать условную компиляцию?
                                +1
                                `if constexpr` позволяет
                                  +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
                                  }

                                  не сделаешь.

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

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

                                0
                                Вот не надо вот от препроцессора отказываться. Это ещё более замедлит принятие С++ на всяких микроконтроллерах и SoC, где до сих пор пишут на С образца семьдесят лохматого года.
                                  +1
                                  пишущие на си образца семидесятых годов заведомо не аудитория новых стандартов с++
                                    0
                                    Знакомые программисты микроконтроллеров говорили, что не используют плюсы из-за слишком толстой стандартной либы.
                                      +3
                                      Это заблуждение или как говорят, ваши коллеги скорее всего не умеют готовить embedded проекты на С++.
                                      Стандартная либа в таких проектах обычно не используется, а вот все плюшки языка доступны
                                        0
                                        Рекомендую показать вашим знакомым consteval-функции C++.

                                        В комитете присутствующие embedded разработчики были вне себя от радости. Теперь можно легко заставлять компилятор вычислять что-то только на этапе компиляции, без попадания этого в рантайм.
                                          0
                                          Это очень опасное заблуждение, более того C++ компилятор генерирует гораздо более качественный ассемблерный код, умеет в разы лучше оптимизировать и даже линкует большие проекты быстрее поскольку C++ знает гораздо больше о коде чем C.
                                            0
                                            Вот здесь довольно интересная демонстрация, когда С++ справляется лучше С.
                                            youtu.be/PDSvjwJ2M80
                                              +1
                                              Что там за опасное заблуждение, простите? Комментатор вам сказал «станадртная либа жирная для embedded» — это никто оспаривать не будет, даже члены комитета С++. Почему вы пытаетесь что-то другое в комменте видеть?
                                              Из-за того что обработка исключений генерирует code-bloat, и появился
                                              www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf
                                              очередной метод обработки ошибок. С текущей реализацией STL под bare metal очень и очень слабо юзабелен.

                                              Я сам мудохался с тем чтобы под вполне себе комфортные 8мб на плюсах писать. Да, в итоге все же остановился на коде с поддержкой исключений, но какие же они жирные…
                                                +3
                                                Опасное заблуждение в том, что из-за std они не используют плюсы вообще. Но кто мешает писать свои классы с noexcept или просто писать очевидный код? Кто мешает использовать noexcept реализации. Да и вообще из личных примеров я месяца три назад просто пересобрал «драйвер» для Ethernet контроллера для одной ужасной железки как C++ код убрав директивы и он стал работать быстрее и стал более cache friendly вот просто так, без изменений кода. Без C++ я банально не могу писать в том же Embedded удобные вещи.
                                                  +1
                                                  Нет, помимо std там там есть и концептуальные проблемы.
                                                  Dan Saks потрясающее видео на эту тему сделал:
                                                  www.youtube.com/watch?v=D7Sd8A6_fYU
                                                  Можно сколько угодно распинаться о преимуществах С++, усилия будут тщетны, пока разработчик на С не будет слышать то что лично ЕМУ нужно.
                                                    +2
                                                    ембед сишники вообще народ сложный. Основных аргумента против плюсов у них три: «stl не влазит в контроллер» (ты и на си им пользоваться не сможешь), «исключения раздувают код» (noexcept или выключи их), «шаблоны раздувают код» (при этом заменяют шаблоны макросами, которые так же инстанцируются по месту и раздувают код точно не меньше). Так что им нужно то? Даже designated initializers уже завезли. Это слабо похоже на взвешенную гражданскую позицию.
                                                      0
                                                      Ну а что плюсы могут дать эмбеду, если stl не брать, шаблоны не использовать, исключения отключить? Много вы тех же плюсовых либ, допустим, в таких условиях скомпилите? А сишные либы у них и без этого геморроя работают.
                                                      Классы? Деструкторы им, как правило, не нужны, потому что память чаще всего статически выделяется. Две с половиной виртуальных функции можно и руками вызвать через указатели или switch. Писать аргумент, передаваемый в местном аналоге ECX, они привыкли справа от названия функции, а не слева, так что синтаксический сахар тоже мимо.
                                                      Ну то есть какие-то преимущества у плюсов есть, но ни одной киллер-фичи конкретно для эмбеда нет. При том что плюсы намного, НАМНОГО сложнее как язык.
                                                        +1
                                                        Если вы выкинете из C++ все, что перечислили, то оставшийся язык будет не сложнее C. И писать на нем будет так же убого и грустно, как и на C. Хотя останутся еще такие приятные вещи, как ссылки, перегрузки функций и большая типобезопасность.

                                                        Но вот с какого перепугу вы решили отказаться от шаблонов и классов? Про их оверхэд можете рассказать?
                                                          0
                                                          Ну там выше пишут, что «шаблоны раздувают код», не я придумал.
                                                            +1
                                                            А еще там пишут вот что:
                                                            «шаблоны раздувают код» (при этом заменяют шаблоны макросами, которые так же инстанцируются по месту и раздувают код точно не меньше).
                                                            Но это вы почему-то игнорируете.
                                                              0
                                                              Вот честно, шаблоны — это одна из самых сложных штук в плюсах. Первые 10 лет её вообще никто не понимал, вместо stl все юзали свои велосипеды на виртуальных функциях. Макросы тоже не сахар, но в них рядовому быдлокодеру не надо «понимать», ими можно просто пользоваться.
                                                                +2
                                                                Первые 10 лет её вообще никто не понимал
                                                                Отучаемся говорить за всех. И про понимание, и про юзание велосипедов с виртуальными функциями.

                                                                В 90-е с шаблонами главная проблема была в том, что не во всех компиляторах они поддерживались. Я, например, начал использовать шаблоны где-то с 1995-го. Но года до 1998-го или даже до 2000-го приходилось оглядываться на компиляторы, в которых шаблонов не было вообще.
                                                                  +1
                                                                  я выше давал ссылку на доклад
                                                                  code::dive conference 2015 — Bartosz Szurgot — C++ vs C the embedded perspective

                                                                  там показан пример, как раз на основе шаблона, который уменьшает размер бинарника ( часть кода становится просто не нужна), и увеличивать скорость работы по этой же причине ( проверки if удаляются за ненадобностью)
                                                            +2
                                                            > Ну а что плюсы могут дать эмбеду, если stl не брать, шаблоны не использовать, исключения отключить?

                                                            • RAII (да, даже в embedded надо порой чистить ресурсы)
                                                            • constexpr и conseval
                                                            • алгоритмы ( и их можно взять из STL, они на исключения и RTTI не завязаны, кроме пары исключений)
                                                            • constexpr и consteval
                                                            • ООП (да, внезапно c ООП код получается более читаемый)
                                                            • Ссылки
                                                            • Type safety
                                                            • Частичное невелирование проблем а аслиасингом — большая производительность и меньший по размеру код
                                                            • ??? (наверняка что-то забыл)
                                                              +1
                                                              Давайте только честно.

                                                              RAII — отличная концепция… для языка с исключениями, но без finally. Так-то ресурсы можно и в процедурном стиле почистить.
                                                              Когда в эмбед завезут constexpr и особенно consteval — ещё неизвестно, а макросы вот они тут.
                                                              Алгоритмы — это книжка Кормена сотоварищи.
                                                              В ООП стиле можно писать и на С (про сахар см. выше замечание про расположение аргумента this).
                                                              Type safety сводится к тому, что у вас есть три с половиной типа: int, int*, (int*)() и иногда struct*. Структуры дадены системными библиотеками и железом, и прикрутиться к ним с этими вашими классами не так-то просто.
                                                              Отсутствие ссылок компенсируется тем, что nullptr указывает на вполне себе доступную область памяти.
                                                              Ну в общем всё перечисленное это клёво, модно, молодёжно, но киллер-фичей не является (кроме м.б. consteval и таки алгоритмов).
                                                                +2
                                                                RAII — отличная концепция… для языка с исключениями, но без finally. Так-то ресурсы можно и в процедурном стиле почистить.

                                                                Алгоритмы — это книжка Кормена сотоварищи

                                                                зачем делать 100 раз то, что можно сделать (как правило, сделали за тебя) единожды?

                                                                Когда в эмбед завезут constexpr и особенно consteval — ещё неизвестно, а макросы вот они тут.

                                                                берем обычный gcc, ставим таргетом контроллер, получаем с++17 уже сегодня.

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

                                                                их можно обернуть и забыть о том, что это сырые структуры

                                                                Отсутствие ссылок компенсируется тем, что nullptr указывает на вполне себе доступную область памяти.

                                                                по стандарту nullptr (в отличие от NULL) может указывать только на заведомо недоступную область памяти
                                                                  0
                                                                  зачем делать 100 раз то, что можно сделать (как правило, сделали за тебя) единожды?

                                                                  Далеко не все алгоритмы работают со статическими массивами языка С. А всякие сбалансированные деревья стиральной машине не нужны.
                                                                  берем обычный gcc, ставим таргетом контроллер, получаем с++17 уже сегодня.

                                                                  Грустное ха-ха три раза. ДАЖЕ если gcc знает целевой машинный код (что не факт), это ещё ничего не значит. Потому что набор железа, конфигурация памяти, соглашение о вызовах, нестандартная линковка, системные либы на несовместимом с GCC диалекте — всё это превращает затею в скачку по граблям. Как правило, у вас есть компилятор от производителя, который принимает «что-то похожее на Си», а всё остальное от лешего.
                                                                  их можно обернуть и забыть о том, что это сырые структуры

                                                                  Дети, не слушайте дядю, он говорит глупости.
                                                                  В классе, обёрнутом вокруг системной структуры, вы:
                                                                  1. не можете использовать наследование
                                                                  2. не можете использовать полиморфизм, ни виртуальный, ни просто перегрузку
                                                                  3. инкапсуляцию использовать можете, но это вам ничего не даст
                                                                  4. не можете использовать деструкторы
                                                                  5. и final у вас тоже нет, не завезли.

                                                                  Поясняю.
                                                                  Допустим, вы воткнули в класс-обёртку виртуальную функцию.
                                                                  Это значит, что перед структурой появился указатель vptr на таблицу виртуальных функций.
                                                                  Системные либы про него ничего не знают, и тупо копируют память без вашего vptr.
                                                                  В итоге вам рано или поздно вернут объект, у которого мусор вместо vptr (и об этом никто не знает). Пояснять, чем закончится вызов метода?
                                                                  Что хуже, вы можете даже не понять, что у вас появился vptr. Это может быть перегруженная внешняя функция, например. В двух вариантах, с конверсией типа аргумента и без. Возможно шаблонная, да. Просто заинклюдили header-only библиотечку и ага.
                                                                  С дополнительными полями аналогично, только растут они в памяти сверху, а не снизу. Но точно также могут потеряться внутри системы, или вы можете затереть память, выделенную системой.
                                                                  Теперь допустим вы огородили поля данных модификатором private, нагородили геттеры-сеттеры и добавили в них логику. И до кучи влепили деструктор.
                                                                  Беда в том, что системные либы не знают про ваши сеттеры и деструкторы. Т.е. они в ваших тестах вызываются, а в процессе прохождения через либу — нет. Счастливой отладки!
                                                                  по стандарту nullptr (в отличие от NULL) может указывать только на заведомо недоступную область памяти

                                                                  Ага, ага, по стандарту.
                                                                  Допустим, у вас всего 256 байт (не мега- и не кило, просто байт) ОЗУ. Как думаете, можно ли читать адрес 0х00?
                                                                    +4
                                                                    > Дети, не слушайте дядю, он говорит глупости.

                                                                    Кажется другой дядя не умеет в ООП. Прятать стрёмные системные вызовы за красивыми интерфейсом весьма просто.
                                                                    Было:
                                                                    int fd = open("light_device");
                                                                    light_settings s{0xf1, 100};
                                                                    ioctl(fd, SET_LIGHT, &s);
                                                                    close(fd);

                                                                    Стало:
                                                                    Light lamp("light_device");
                                                                    lamp.set(Green, 10_kHz);

                                                                    Виртуальными функциями и правда не воспользовались… Если у вас в руках молоток, это не значит что всё вокруг становится гвоздями.
                                                                      –1
                                                                      Да-да, вот вам не успел ответить. Расскажите про строчку close(fd).
                                                                      Вот допустим, что в 99% случаев мне нужно зажечь лампочку в одном месте (допустим, сейчас), а погасить в непредсказуемом другом. По асинхронному таймеру, или если юзер нажмёт кнопку, или (здесь большой список или).
                                                                      Зачитайте, пожалуйста, все преимущества RAII и ООП в обозначенном мной случае.
                                                                        0
                                                                        Расскажите про строчку close(fd).
                                                                        Вы сперва расскажите как в вашем гипотетическом сценарии будете передавать fd из места, где вызвали open() в место, где вы хотите вызвать close().

                                                                        Поскольку вам привели самодостаточный пример. Вы его пытаетесь во что-то преобразовать, но не показываете во что именно.
                                                                          0
                                                                          fd будет глобальной статической переменной. Да-да, я знаю, сейчас меня закидают помидорами и скажут ффуу, но это самый экономный способ.
                                                                          Дальше она равна 0 если файл закрыт или не 0 если открыт. Проблем с гонками сигнала нет, т.к. можно безопасно закрывать закрытый или даже некорректный номер файла.
                                                                            +2
                                                                            fd будет глобальной статической переменной.
                                                                            А теперь представьте, что у вас lamp будет глобальной переменной.

                                                                            При этом, представьте, у вас может быть шаблонный класс Light, который настраивается политикой поведения: RAII или не RAII. Например, у вас может быть:
                                                                            static Light<NO_RAII> red_lamp;
                                                                            ...
                                                                            void turn_on() {
                                                                               red_lamp.open("/device/red_lamp");
                                                                               red_lamp.on();
                                                                               Light<RAII> green_lamp{"/device/green_lamp", Light<RAII>::on};
                                                                               ...
                                                                            }
                                                                            void shutdown() {
                                                                              if(red_lamp.is_on()) {
                                                                                red_lamp.off();
                                                                                red_lamp.close();
                                                                              }
                                                                              ...
                                                                            }
                                                                            

                                                                            И для red_lamp у вас не будет ни конструктора, ни деструктора. А для green_lamp будет и то, и другое. При этом накладные расходы будут такие же, как случае, если бы вы все это реализовывали ручками на чистом C.
                                                                          +2
                                                                          Move семантика вам поможет с владением. См. примеры ASIO например.

                                                                          А если вам нужна статическая переменная (вы именно так предлагаете решать проблему ниже в коментариях) — делайте статическую lamp, никто вам не мешает.
                                                                        +3
                                                                        Далеко не все алгоритмы работают со статическими массивами языка С. А всякие сбалансированные деревья стиральной машине не нужны.

                                                                        «со статическими массивами языка С» работают std::begin/std::end, возвращающие достаточно для передачи в любой алгоритм. Проблемы могут быть разве что с std::sort, выделяющим память

                                                                        Как правило, у вас есть компилятор от производителя, который принимает «что-то похожее на Си», а всё остальное от лешего.

                                                                        тогда и вопрос не стоит. Мы же всё-таки говорим о тех случаях, когда можно использовать с++ вместо си.

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

                                                                        я вас здесь остановлю и приведу минимальный пример, демонстрирующий где вы неправы: при касте указателя на наследник к указателю на базовый класс адрес может меняться, и он будет указывать на корректный инстанс базового класса. А если «системная либа» вдруг лезет в память вокруг переданного ей объекта, в ней UB

                                                                        Да и оборачивать надо с умом. Например, можно не наследованием, а композицией. По-хорошему, небезопасные сишные кишки в плюсовом коде лучше полностью обернуть, от греха подальше. Благо обычно это можно сделать без оверхеда.
                                                                          –1
                                                                          «со статическими массивами языка С» работают std::begin/std::end

                                                                          Да?! Ну вот у меня есть указатель wtf*, поясните, как будет работать std::end.
                                                                          при касте указателя на наследник к указателю на базовый класс адрес может меняться, и он будет указывать на корректный инстанс базового класса

                                                                          простите, вы не понимаете, как работает С++. Указатель на инстанс будет корректный, но только, ещё раз подчеркну, только с точки зрения конкретного компилятора С++.
                                                                          А если «системная либа» вдруг лезет в память вокруг переданного ей объекта, в ней UB

                                                                          Нет, с системной либой всё ок, это у вас в плюсовой программе будет даже не UB, а просто баг.
                                                                          Да и оборачивать надо с умом. Например, можно не наследованием, а композицией.

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

                                                                            +1
                                                                            Да?! Ну вот у меня есть указатель wtf*, поясните, как будет работать std::end.

                                                                            статический массив языка си, о котором шла речь, это не wtf*. Впрочем, указатель является корректным random access итератором. begin =wtf, end = wtf + size. Вы же знаете размер статического массива?

                                                                            простите, вы не понимаете, как работает С++. Указатель на инстанс будет корректный, но только, ещё раз подчеркну, только с точки зрения конкретного компилятора С++.

                                                                            Нет, с системной либой всё ок, это у вас в плюсовой программе будет даже не UB, а просто баг.

                                                                            А можете привести пример? Пока что я не в состоянии интерпретировать ваши утверждения из предположения что вы правы

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

                                                                            компиляторы с++ ныне более чем способны справиться с инлайнингом пары функций
                                                                      +2
                                                                      для языка с исключениями, но без finally.
                                                                      Внезапно, RAII помогает и для обычного случая return, и для обычного break.

                                                                      А про finally. Его что, уже в стандарт C завезли?
                                                                      Type safety сводится к тому, что
                                                                      у вас void* не будет автоматически каститься к чему угодно.
                                                                        +2
                                                                        > Type safety сводится к тому, что у вас есть три с половиной типа

                                                                        Вот вам типичный код на embedded:
                                                                        set_light(LIGHT_GREEN, 10);
                                                                        

                                                                        Читается как-то не очень, а ещё оба параметра на вход имеют тип int. Ошибиться крайне легко.

                                                                        А вот как это можно написать в C++
                                                                        set_light(Green, 10_kHz);
                                                                        

                                                                        Получается намного читаемее, да и компилятор не даст вам перепутать порядок аргументов:
                                                                        enum Color: unsigned short { Red = 0x1, Green = 0xF1, };
                                                                        enum Frequency: unsigned {};
                                                                        constexpr Frequency operator"" _kHz(unsigned val);


                                                                        По остальному уже отписались… Отдельно замечу, что писать алгоритмы в C стиле — это плохо для оптимизатора (см бенчмарки qsort) и как правило нечитаемо.
                                                                          +2
                                                                          Ой-ей, я уже сам не рад, что ящик Пандоры с этим обсуждением открыл :D

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

                                                                          Может быть, вышеприведенные примеры и не убедят закоренелого сишника, но по крайней мере помогут человеку, который уже знаком с обоими языками, и думает на чем писать проект под embedded — на C или на урезанном C++.
                                                                      +2
                                                                      Ну а что плюсы могут дать эмбеду, если stl не брать, шаблоны не использовать, исключения отключить?

                                                                      из stl всё еще остается хороший пласт header-only библиотек/классов, навскидку алгоритмы, утилитарные классы аля tuple/pair/variant/optional/bitset, более широкая и консистентная мат. библиотека. И не забывайте про фичи самого языка — всякие range-based for, constexpr, лямбды, перегрузки, инициализация по умолчанию. Опять же, шаблоны могут многое из того чего не умеют макросы

                                                                      Классы? Деструкторы им, как правило, не нужны, потому что память чаще всего статически выделяется

                                                                      и вдруг возникают сценарии типа «вот здесь на входе подними бит, а на выходе опусти», в которых RAII превосходно себя показывает

                                                                      Ну то есть какие-то преимущества у плюсов есть, но ни одной киллер-фичи конкретно для эмбеда нет

                                                                      Например, типобезопасность — нет нужды постоянно кастить указатели из/в void*/char*. Это дает компилятору/анализатору больше информации о данных и позволяет лучше диагностировать ошибки и оптимизировать.

                                                                      При том что плюсы намного, НАМНОГО сложнее как язык.

                                                                      но писать на них код во столько же раз проще, на подмножестве языка едва превосходящим по объему си.
                                                      +1
                                                      Не могу найти на фотке автора ranges. Где радостный Эрик?! =)
                                                        0
                                                        Сидит почти что в центре фотографии. Но на фото не попал Кейси Картер — второй по величине вкладчик в Ranges :(
                                                          0
                                                          А Рядом с ним Гор Нишанов?
                                                            0
                                                            Ага. Если хотите — могу выложить фотографию в оригинальном разрешении. Там больше лиц видно, и даже меня можно разглядеть в зеркале :)
                                                        +2
                                                        Меня мучит вопрос, может кто подскажет: в бустовом variant и optional есть поддержка ссылок, в std их нет. Я читал, что это из-за неопределенности оператора присваивания. Но может стоило все-таки пойти по пути буста? Мне лично очень часто нужна опциональная ссылка, да и вариант со ссылкой тоже. Почему приняли именно такое решение, которое (кажется, сильно) ограничивает сферу примененя этих типов?
                                                          +1
                                                          Ссылки напрямую не поддерживаются, но всегда можно написать std::variant от std::reference_wrapper и получить поведение близкое к Boost.

                                                          А проблему вы верно указали — поведение std::varaint<int, int&> при присваиваниях будет определяться внутренним содержимым. Это показалось странноватым комитету, и решили не поощрять подобное и не переусложнять класс variant. Те кому всё же нужно подобное поведение всегда могут воспользоваться reference_wrapper
                                                          +2
                                                          Может кто-нибудь разъяснить что значит dynamic_cast внутри constexpr-выражения? Как это вообще понимать?
                                                            +1
                                                            А в чём проблема? Известен тип и значение аргумента, можно вычислить результат. Если такое приведение невозможно, результатом будет nullptr.
                                                              +2
                                                              Тогда получается, что это просто static_cast, который возвращает nullptr в случае неудачи, так?
                                                                +3
                                                                Да. Ну и вам будет проще переносить имеющийся код на constexpr — dynamic_cast будет просто работать, не надо будет их заменять на странные конструкции с std::is_constant_evaluated.
                                                                  +2
                                                                  Фух, понял! Благодарствую, а то с утра не отпускало:)

                                                                  (Плюсануть не могу, неполноправный.)
                                                              +2
                                                              Если мы создаем переменную в 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
                                                                Ага, понятнее, спасибо! А в случае, если переменная создана не в constexpr-контексте, тогда и функция перестанет быть constexpr, так?
                                                                  0
                                                                  Да, всё верно. Функция будет выполняться на рантайме. Или будет ошибка компиляции если попробуете использовать эту функция в том месте, где компилятор требует вычисление на этапе компиляции:

                                                                  void do_something() {
                                                                      /*constexpr*/ forty_two ft{};
                                                                  
                                                                      // Следующая строчка не соберётся. Компилятор будет жаловаться,
                                                                      // что переменная `ft` не известна на этапе компиляции и он не может
                                                                      // выполнить `try_say` как constexpr функцию.
                                                                      static_assert(try_say(ft) == 42); 
                                                                  }
                                                                  0
                                                                  А как там с исключениями в constexpr-выражениях? Ну тоесть если try/catch есть — то все понятно, а если нет? Или если есть дальнейший проброс исключения? Что будет? Ну тоесть, понятно, что в итоге все должно свестись к ошибки компиляции, но вот сам вид этой ошибки не очень понятен.
                                                                    0
                                                                    Кидать исключения в constexpr по прежнему нельзя. Если при constexpr вычислении будет выполнена строчка с throw — компиляция прервётся и будет выведено сообщение об ошибке.
                                                                      0
                                                                      Ага, понятно, спасибо, про бросать — понятно.
                                                                      А про не ловить? Вот если в вашем примере заменить dynamic_cast с указателей, на ссылки и приводить не к тому типу, да еще и try/catch-ем не обложить, что будет?
                                                                      Или dynamic_cast на ссылках нужно обязательно заварачивать в try/catch блок, при чем в месте вызова?
                                                                        0
                                                                        Если dynamic_cast захочет кинуть исключение в constexpr, то будет ошбка компиляции, и никакие catch(...) не помогут.
                                                                +6

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

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

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

                                                                      +3
                                                                      Мне кажется, Вы говорите про Common Lisp :)
                                                                        +2
                                                                        Можно посмотреть на механизм текстовых 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, может стать доступной через метаклассы. Но, наверное, не все.
                                                                          0
                                                                          Не откроет ли это ящик Пандоры?
                                                                            0
                                                                            Всенепременно откроет (если уже не открыли, с тьюринг-полными шаблонами). Но тем
                                                                            интереснее:)
                                                                            +1
                                                                            Ох, eval()-а нам только и не хватало.
                                                                          +1
                                                                          А почему Networking отложили?
                                                                            +2
                                                                            Возникли подозрения, что дизайн можно улучшить, используя последние новинки C++20 (в основном концепты, и немного ranges).
                                                                              0
                                                                              Так автор Networking вроде на cppcon об этом прямо говорил, что «ребейзить» надо.
                                                                                0
                                                                                О! А можно ссылочку на видео, а то я найти не могу :(
                                                                                  +1
                                                                                  www.youtube.com/watch?v=hdRpCo94_C4 (да, это не автор TS)
                                                                                  вот это вроде, долго чет искал) Таймкод с пруфом про «надо ребейзить» не подскажу. Если я ошибся, то может и не это видео вовсе. Извините в случае чего.
                                                                            0
                                                                            А про алгебраические типы данных и паттерн-матчинг что-нибудь известно? Вроде как перед этой встречей появилось несколько конкурирующих предложений на эту тему.
                                                                              0
                                                                              До их рассмотрения дело не дошло. Зато успели немного пообсуждать монадические интерфейсы для std::optional.
                                                                                0
                                                                                До их рассмотрения дело не дошло.
                                                                                Жаль. Видимо, придется ждать C++23 или даже C++26.
                                                                                Зато успели немного пообсуждать монадические интерфейсы для std::optional.
                                                                                Дурное дело не хитрое.

                                                                                Шутка :)
                                                                                  0
                                                                                  Можете вкратце описать результаты обсуждения? Было бы очень интересно увидеть когда-нибудь что-то такое.
                                                                                    0
                                                                                    Обсуждали предложение P0798. В отсновном выбирали имя для функции map/transform и определялись с требованиями к аргументам данной функции. В C++20 попасть скорее всего не успеет.
                                                                                    0

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

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

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

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

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

                                                                                        Так что когда примут в стандарт, некоторые компиляторы часть функций не смогут сделать constexpr в течение длительного времени.
                                                                                        0
                                                                                        Про странный пример… Всё сводится к вычислению вот этих двух строчек с переменной `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
                                                                                        К C++20 многие (и я в их числе) хотят увидеть в стандарте контейнеры, которыми можно пользоваться на этапе компиляции.

                                                                                        А можно юзкейсов немного? А то я пока даже в принципе не понимаю зачем нужны constexpr. constexpr контейнеры же для меня вообще rocket-science какой-то.
                                                                                          +1
                                                                                          Пример простой — рефлексия
                                                                                            +2
                                                                                            Самый ожидаемый мной контейнер — 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.
                                                                                              0
                                                                                              Любителям метапрограммирования с constexpr std::vector откроются новые возможности. Так например подобное нечитаемое безобразие просто не надо будет писать, так как можно будет обойтись std::vector и алгоритмами из стандартной библиотеки. Метапрограмный код получится читаемый, а не тот что мы имеем в C++14/17.


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

                                                                                              Upd: а, там массив возвращается; ну да, вектор полезен был бы
                                                                                                0
                                                                                                А чем не вариант для константных строк использовать string_view? Если она инициализируется литералом, время жизни обеспечено. Можно даже отнаследовать какой нибудь literal_view с constexpr конструктором из массива char.
                                                                                                  0
                                                                                                  Для константных — самое то. Но вот выше люди коментируют, что хотят макросами имена функций и переменных генерировать. Для того чтобы это можно было делать через рефлексию, а не макросы, нужен constexpr string.
                                                                                                0
                                                                                                constexpr нужны для манипуляциями над данными в RO памяти, которых в программах может быть достаточно много. Например, у нас есть массив, данные в котором мы ищем по индексу. Как не нафакапить при заполнении массива и не промахнуться с индексом? Очень просто, написать constexpr функцию, проверяющую валидность массива и вызвать её из static_assert.

                                                                                                А теперь допустим мы ходим искать в этом массиве не по индексу, а по содержимому.
                                                                                                Сделаем constexpr хэшмапу и будем искать за (примерно) константное время. Впрочем, этот велосипед был скорее на поиграться с возможностями нового с++; в мире розовых поней я лучше подожду constexpr std::unordered_map.
                                                                                                +4
                                                                                                Всё очень круто! Но будет ли помещаться С++20 в голову разработчику?
                                                                                                Нужен новый Майерс, раз уж старый Майерс завязал с объяснениями хитростей С++!
                                                                                                  0
                                                                                                  Для этого даже создали отдельную подгруппу в комитете :-) Если у Вас есть идеи, как можно помочь — то добро пожаловать :)
                                                                                                    +1
                                                                                                    Но будет ли помещаться С++20 в голову разработчику?
                                                                                                    В мою и C++98 не помещался. Но, как показала практика, если ты не разрабатываешь компилятор C++ или стандартную библиотеку для C++, то знать _весь_ C++ и не нужно.
                                                                                                      +1
                                                                                                      Уверяю вас, вы не одиноки!
                                                                                                      +2
                                                                                                      Но будет ли помещаться С++20 в голову разработчику?


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

                                                                                                      Я немного не следил за событиями: в других языках тоже жалуются?
                                                                                                      0
                                                                                                      del
                                                                                                        0
                                                                                                        А как поживает constexpr с восклицательным знаком?
                                                                                                          +1
                                                                                                          Это же упомянутый consteval? Или что-то ещё?
                                                                                                            +2
                                                                                                            Да, проморгал. Спасибо!
                                                                                                            Слава богу, решили выпилить этот восклицательный знак, фуф.
                                                                                                              0
                                                                                                              Ну там и доллар из метаклассов и рефлексии выпилили.
                                                                                                                0
                                                                                                                И это проморгал :( Ссылку можно?
                                                                                                                  0
                                                                                                                  По метаклассам вот последняя ревизия:
                                                                                                                  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 ревизии посмотрите
                                                                                                                    0
                                                                                                                    Спасибо!

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


                                                                                                                    Ммда, ну, поживем-увидим.
                                                                                                                      0
                                                                                                                      Это еще что. Там на проперти вообще ужас какой-то. (то что в целом метаклассы превращаются в эдакие функции, я не вижу плохого, но надеюсь синтаксис еще доработают. Саттер тоже не в восторге).
                                                                                                          +2
                                                                                                          Интересно было бы услышать тех, кто 2D графику в опросе выбрал — как вы будете это использовать, для чего? Использовать стандартную библиотеку без какого-либо графического фреймворка?
                                                                                                            0
                                                                                                            Рисовать таблицы, графики, обрабатывать изображения, простейший GUI (да, без фреймворка). Лично мне сильно не хватает изкоробочной возможности отрисовать картинку со статистикой и отдать её пользователю как веб страницу.
                                                                                                              0
                                                                                                              Вы мимо, но спасибо)

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

                                                                                                              Ну пользователю-то картинку и пожать придется? я почитал
                                                                                                              www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0267r7.pdf
                                                                                                              там же рендеринг только.
                                                                                                              Не будут же туда еще видео кодеки пихать)
                                                                                                                0
                                                                                                                Там есть сохранение в формате изображений (PNG и JPEG точно были).
                                                                                                                  0
                                                                                                                  Да, я виноват, просмотрел, 13.9 раздел, если кому интересно.
                                                                                                                  В такой постановке, согласен, может быть полезно для минималистичного взаимодействия. Все равно меня немного напрягает «внешняя зависимость» в виде PNG кодеков в стандартной библиотеке, и как это все будет специфицировано (с учетом того что периодически всплывают уязвимости в libpng той же).
                                                                                                                    0
                                                                                                                    В юникоде, стандартной библиотеке и demanglingе тоже уязвимости всплавают. Пока всё норм.
                                                                                                                +2
                                                                                                                то есть подтянуть внутрь стандартной библиотеки libpng/libbmp/libsvg? Или в каком виде отрисовывать? Почему не скомпилировать это wasm и рисовать в канвас из локального фреймбуффера если это веб?
                                                                                                                  0

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

                                                                                                                    +2

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

                                                                                                                      0
                                                                                                                      Смущает. Хотя наверное было бы неплохо иметь некоторый кроссплатформенный интерфейс для кодеров/декодеров изображений и аудио до кучи. Но это не раст с его типажами, поэтому довольно сомнительно все это.
                                                                                                                        0
                                                                                                                        А как в раст подобные типажи помогут?
                                                                                                                          0
                                                                                                                          В раст можно прокинуть некоторый интерфейс графики который реализовать отдельными крейтами. Но тут же возникает зачем оно в стандартной библиотеке. Да и боли с рисованием там тоже особо нет.
                                                                                                                    +2
                                                                                                                    А зачем это в стандарной библиотеке?
                                                                                                                      0
                                                                                                                      Чтобы можно было пользоваться, а не страдать. Networking, std::thread, Filesystem служат той же цели (впрочем как и вся стандартная библиотека).
                                                                                                                        +3
                                                                                                                        С++ нужна не раздутая стандартная библиотека, а нормальный репозиторий для всего этого хозяйства.
                                                                                                                          0
                                                                                                                          C++ в первую очередь нужна функциональная стандартная библиотека.
                                                                                                                            0
                                                                                                                            Согласен, но может это хотя бы сделают на откуп вендорам, как было со стандартизацией больших интов и GC? просто например какой-нибудь вендор под embedded может и не захотеть реализовать стандарт под свою железку. (хотя чего я, как будто бы сегодня их заставляют реализовывать весь стандарт).
                                                                                                                              0
                                                                                                                              Сейчас наоборот идёт движение в сторону того, чтобы явно разметить в стандартной библиотеке embedded/freestanding части. Тоесть выделить некое подмножество стандартной библиотеки, которое работает на любой платформе, даже на такой где нет оперативной памяти, файловой системы и проч.
                                                                                                                                0
                                                                                                                                Ееее! Это очень крутое движение, рад был про это слышать (удивительно как я такое пропустил).
                                                                                                                          +2
                                                                                                                          Networking, std::thread, Filesystem

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

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

                                                                                                                            Поправьте меня если я не прав.
                                                                                                                              0
                                                                                                                              2D графика в последнее время очень не сильно изменилась по той простой причине, что это простой подход, но упершийся в потолок развития. Императивный подход (а-ля, нарисуй круг, линию, потом дугу) весьма тормозной, гораздо производительнее использовать 3Д библиотеки и рисовать ими 2D.
                                                                                                                              Или, с другой стороны, дальнейшее развитие 2D рисования — это выкинуть текущее АПИ в помойку и сделать новое с нуля; что и происходит (но только в 3D) — Vulkan, Metal
                                                                                                                      +3
                                                                                                                      А как поживает P0631R0? Появится ли наконец-то в С++20 стандартная константа для числа Пи? Или так и будем 4*atan(1)?
                                                                                                                        0
                                                                                                                        Что-то мне не очень понятна ситуация 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
                                                                                                                          отдельные аттрибуты для импорта/экспорта — чисто msvc-шная проблема и если они её решат, то лучше будет всем.
                                                                                                                            0
                                                                                                                            Дело не в отдельный аттрибутах (я про них не упоминал). Уверен, разработчики смогут справиться. Речь о том что разные имена в ABI, и это не покрыть фичами языка (либо создавать новый ABI которым никто не будет пользоваться).
                                                                                                                              0
                                                                                                                              причем тут msvc под linux тоже пользуются visibility — экспортируешь символ — default, по умолчанию hidden
                                                                                                                                0
                                                                                                                                по умолчанию в visibility значение (внезапно) default — экспортировать/импортировать символ
                                                                                                                            –2
                                                                                                                            Язык без «изкоробочной» поддержки UTF-8 в 2020 году это провал, ребята.
                                                                                                                            Если комитет этого не понимает, то анонсированного выше в комментариях С++35 просто не будет.
                                                                                                                              +1
                                                                                                                              C++ это такой язык, что даже не будь изкоробочной поддержки в стандартной библиотеке чего угодно, это бы не привело его к провалу.
                                                                                                                              Существующая практика такова, что почти всегда для реализации нужных функций нужны сторонние библиотеки.

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

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

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

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

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

                                                                                                                                    Так что вы уже со своим тезисом «никто не пользовался» не правы. Ну и дальше, если копнуть, везде такая же история.
                                                                                                                                      0
                                                                                                                                      Ребят, да я про тенденцию говорю. Тогда на плюсах писали реально всё, из конкурентов был или чистый Си или Паскаль/Дельфи.
                                                                                                                                      Сейчас мы ниши перечисляем. Вот мол у автора статьи ОСь и браузер написаны на плюсах. А у меня ось на джаве, а браузер потихоньку на раст переписывают.
                                                                                                                                      Если бы лямбды, auto и нормальный for появились на 10 лет раньше, этого бы не было.
                                                                                                                                        0
                                                                                                                                        А у меня ось на джаве
                                                                                                                                        Это какая?
                                                                                                                                        Если бы лямбды, auto и нормальный for появились на 10 лет раньше, этого бы не было.
                                                                                                                                        Да ладно, устойчивая тенденция миграции с C++ на Java началась где-то в 2000-ом или 2001-ом. К 2004-ому она уже была вполне себе четкой. И Java тогдашняя по выразительности с C++98 не могла соревноваться.

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

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

                                                                                                                                          Ведроид жи ну. Да-да, я знаю, что там внутре у ней неонка, в смысле линукс, но он тоже не на плюсах написан.
                                                                                                                                            +2
                                                                                                                                            У Андроида практически весь userspace написан на C++, включая линкер.
                                                                                                                                              0
                                                                                                                                              Ну так не на Java же OS написана. Пока. Вроде как Google хочет со временем на Фуксию перевести, которая уже на плюсах пишется.
                                                                                                                                                +1
                                                                                                                                                ОС это не только и не столько ядро. Это библиотеки, утилиты, планировщики, рюшечки, окошечки и прочие пакетные менеджеры. Посмотрите на зоопарк дистрибутивов Линукса — перевести прод с условной федоры на убунту не сильно проще, чем с винды (из-за чего всякие докеры и появились).
                                                                                                                                                Возврат гугла к плюсам обусловлен, в первую очередь, тем, что у самой java проблем выше крыши, причём как технических, так и юридических и организационных. Ну и да, здесь надо похвалить комитет, плюсы сейчас развиваются действительно поживее, чем java.
                                                                                                                                                  0
                                                                                                                                                  Это библиотеки, утилиты, планировщики
                                                                                                                                                  И вот это все на C или C++.
                                                                                                                                                  рюшечки, окошечки и прочие пакетные менеджеры
                                                                                                                                                  А это уже относится к ОС, если под ОС понимать что-то вроде Windows. А вот в том же Linux-е есть сама ОС и есть Desktop Environment. Вот окошечки-рюшечки — это про Desktop Environment, а не про ОС.
                                                                                                                                              0
                                                                                                                                              Слышал что уже длительное время идёт обратная миграция. Процессоры почти перестали расти в тактовой частоте и в основном растут в количестве ядер. Ну и тут grabage collector начинает играть злую шутку: если у вас 1 ядро, и GC отрабатывает за 1мс, то вы теряете 1мс процессорного времени; если у вас 16 ядер, и GC отрабатывает за 1мс, то вы теряете 16мс процессорного времени. Альтернативные подходы к GC обладают аналогичными недостатками.
                                                                                                                                                0
                                                                                                                                                Слышал что уже длительное время идёт обратная миграция.
                                                                                                                                                Да тут сложно оценки сделать. С одной стороны — да, есть прецеденты, когда с Java переходят на C++ (или используют в Java код на плюсах через JNI). С другой стороны, на Java и C# делают тот же самый HFT, где плюсам самое место (и где они хорошо себя чувствуют).
                                                                                                                                                  0
                                                                                                                                                  А можно ткнуть пальцем, где HFT на шарпах/java пишут? Я пониаю когда околовычислительне всякие микросервисы, графики рисовать, отчеты пилить, но вот чтобы прям непосрдественно общение трейдеров — не сышал.
                                                                                                                                                    +1
                                                                                                                                                    Наверное, самый известный — это Lmax со своим Disruptor-ом.

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

                                                                                                                                                    Про разработку на C# в обсуждении на RSDN-е кто-то рассказывал (отсюда и далее вниз по ветке).
                                                                                                                                              +1
                                                                                                                                              давайте перефразируем: раньше выбора не было, а сейчас он появился. Раньше железо не позволяло лишний раз писать на джаве/диезе/питоне, а сейчас позволяет. То, что появилась достойная альтернатива в виде раста — хорошо, но едва ли в ближайшем будущем все забросят свои кодобазы и сбегут на него. У плюсов есть старые детские проблемы, и это не значит что их не надо (или нельзя) поправить
                                                                                                                                                0
                                                                                                                                                Понимаете, если комитет до сих пор спорит, не пора ли в языке сделать, наконец, строки с поддержкой юникода, то конкурировать такой язык будет, как заметил antoshkka, разве что с фортраном за умы седовласых академиков.
                                                                                                                                                  +1
                                                                                                                                                  Комитет не спорит на тему «надо ли», комитет обсуждает как это сделать правильно. Если вы знаете как это делать правильно — то пишите proposal, вас с радостью выслушают.

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

                                                                                                                                                      Тут приличное общество, давайте не будем опускаться в дискуссиях до подобных приёмов.
                                                                                                                                                    0
                                                                                                                                                    предложите навскидку zero-overhead юникод библиотеку
                                                                                                                                                      +1
                                                                                                                                                      А нету таких. Переход на юникод это боль и страдания. Питон страдал несколько лет, php до сих пор страдает с mbstring и func_overload, и так далее. Но вариантов нет, мир уже чуть больше, чем горстка юзеров в англоязычных странах.
                                                                                                                                                      Комитет на то и нужен, чтобы изучить ошибки других, сжать тестикулы в кулак, принять решение и добровольно-принудительно перейти всем сообществом. А не как у нас в плюсах принято, что в языке несколько видов строк, несколько видов «умных» указателей, а к четырём одновременно существующим видам обработки ошибок предлагается добавить ещё столько же. Берёшь либу и не знаешь, что от неё ожидать.
                                                                                                                                                      Есть, в конце концов, буст, где можно обкатать потенциальных кандидатов «в живой природе» до их стандартизации.
                                                                                                                                                        0
                                                                                                                                                        А можно ссылку на историю о страданиях питона? Я думал его изначально с поддержкой делали.
                                                                                                                                                          0
                                                                                                                                                          Строки в Питоне стали юникодовыми только с третьей версии. И это сломало обратную совместимость.
                                                                                                                                                          +1
                                                                                                                                                          «Берёшь либу и не знаешь, что от неё ожидать»
                                                                                                                                                          Пока для меня, основная боль как разработчика, это не то что в С++ нет какой-то там поддержки utf-8, а то что сторонние кроссплатформенные C библиотеки просто используют fopen/stat и т.п. которые разумеется на Win работают, но без поддержки юникода.
                                                                                                                                                          — ffmpeg/vidstab
                                                                                                                                                          — opencv — весь файловый api
                                                                                                                                                          — glog
                                                                                                                                                          — dlib
                                                                                                                                                          (первое что за минуту в голову пришло, тысячи их)
                                                                                                                                                          Да, патчи-то наложить недолго, но е-ёмое, не понимаю я разработчиков библиотек, под винду эти функции существуют два десятка лет, вы делаете «кросплатформенность» и забиваете на поддержку юникода в FS? что с вами не так?
                                                                                                                                                          MS, сделайте уже поддержку setlocale(«utf-8»), чтобы fopen работал как везде, это не лечится)
                                                                                                                                                            0
                                                                                                                                                            With insider build 17035 and the April 2018 update (nominal build 17134) for Windows 10, a «Beta: Use Unicode UTF-8 for worldwide language support» checkbox appeared for setting the locale code page to UTF-8.[a] This allows for calling «narrow» functions, including fopen and SetWindowTextA, with UTF-8 strings. Microsoft claims this option might break some functions (a possible example is _mbsrev) as they were written to assume multibyte encodings used no more than 2 bytes per character, thus until now code pages with more bytes such as GB 18030 (cp54936) and UTF-8 could not be set as the locale.

                                                                                                                                                            Но походу сделано как я понимаю криво, настройка — глобальная общесистемная, выбирается юзером, никакой не setlocale(«utf-8»).
                                                                                                                                                0