Возможно, я скажу банальную вещь, но прошедший год был хорошим годом для С++!

Просто факты:
  • Вышла Visual Studio 2015 с отличной поддержкой возможностей С++14/17 и даже нескольких экспериментальных вещей
  • Вышел долгожданный GCC 5.0
  • С++ набрал серьёзную популярность. Где-то с июля — третье место в Tiobe Ranking
  • На конференции CppCon 2015 было сделано несколько важных анонсов


А теперь об этом и другом немного подробнее


Статус поддержки С++11


Компиляторы Clang, GCC и Intel Compiler имеют полную поддержку C++11.
В Visual Studio не хватает двух вещей: Expression SFINAE — N2634 и C99 preprocessor — N1653

Статус поддержки С++14


Clang и GCC полностью поддерживают C++14. А в общем дела обстоят так:


Изменения с прошлого года отмечены звёздочкой (*)

В Visual Studio 2015 компилятор С++ стал заметно ближе к полному соответствию стандарту, были реализованы Sized deallocation, атрибут [[deprecated]] и поддержка одинарной кавычки в качестве разделителя разрядов в числах.

Хороший прогресс показал и компилятор Intel — они добавили поддержку обобщённых лямбда-функций, инициализацию членов класса (включая агрегатную), плюс всё те же аттрибут [[deprecated]] и поддержку одинарной кавычки в качестве разделителя разрядов в числах.

Статус поддержки С++17


Очевидно, большинство из нас ждёт этого грандиозного события, которое должно уже вот-вот произойти: стандартизации С++17! Да, компиляторам нужно ещё поработать над поддержкой С++11/14, но большинство фич уже реализованы или находятся на последних этапах реализации. Команды разработчиков всех основных компиляторов уже активно экспериментируют с некоторыми новыми фичами будущего стандарта С++17.

Но что включает в себя С++17?
Для полного понимания предмета лучше всего будет прочитать "Мысли по поводу С++17" от Страуструпа. Он выделил три основных приоритета:
  1. Улучшить поддержку масштабирования для больших проектов
  2. Добавить поддержку высокоуровневого параллелизма
  3. Сделать ядро языка проще, улучшить STL


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

  • Модули — n4465, n4466
  • Контракты — n4415
  • ASIO для работы с сетью — n4478
  • SIMD-векторизация — n4454
  • Улучшенные futures — n3857, n3865
  • Корутины — N4402, n4398
  • Транзакционная память — n4302
  • Параллельные алгоритмы — n4409
  • Концепты — n3701, n4361
  • Концепты в стандартной библиотеке — n4263
  • Ranges — n4128, n4382
  • Унифицированный синтаксис вызова — n4474
  • Оператор точка — n4477
  • array_view и string_view — n4480
  • Массивы в стеке — n4294
  • optional — n4480 — optional
  • Свертка выражений — N4295
  • __has_include в условиях препроцессора — P0061R1
  • Файловая система — n4099
  • Множество более мелких изменений


Вот отличный обзор всех потенциальных возможностей С++17.
Те фичи, которые не успеют войти в С++17, войдут в следующий стандарт С++20, который планируется как минорный. С++20 отполирует С++17, как С++14 отполировал С++11.

Core Guidelines


На конференции CppCon в ключевой презентации Бьёрн Страуструп сделал важный анонс: Core Guidelines!

Полная версия гайдлайнов находится на GitHub, вот выдержка из вступления:

«С++ Core Guidelines являются результатом совместной работы группы авторов под руководством Бьёрна Страуструпа, как, собственно, и сам язык С++. В разработку этих рекомендаций вложено много человеко-лет труда людей из множества организаций. Дизайн данных гайдлайнов предполагает их общее применение и широкое распространение, что однако, не исключает ваше право скопировать и изменить их под нужды вашей организации.

Целью разработки данных инструкций является помочь людям использовать современный С++ эффективно. Под „современным С++“ мы подразумеваем С++11 и С++14 (а вскоре и С++17). Мы поможем представить вам как ваш код, который вы начнёте писать сегодня, будет выглядеть через 5 (или 10) лет.»

Поскольку язык становится богаче, современнеее (но в то же время и проще) будет очень полезно иметь такой справочник. Некоторые хорошо известные правила заменены новыми подходами — например, RAII. Переход на них не так прост, особенно, если вы поддерживаете старую кодовую базу и хотите добавить что-нибудь современное в свой код. Core Guidelines разрабатываются коллективно, а значит, должны стать достаточно практичным инструментом.

Речь Бьёрна Страуструпа:


Дополнение к ней от Херба Саттера:


Стандартизация С++


В прошлом году прошли две встречи комитета по стандартизации С++: Кона в Октябре и Ленекса в Апреле.

Пару слов о весенней встрече:


И об осенней:


Намечены следующие встречи комитета по стандартизации в 2016-ом году: во Флориде в феврале и в Финляндии в июне (на этой встрече планируется голосование за стандарт С++17).

Новости мира компиляторов


Visual Studio



GCC



Clang



Intel compiler



Конференции


В прошлом году прошло две важных конференции: CppCon и MettingCpp

CppCon



MeetingCpp



Первый доклад:


и второй:


Заключение


Как мы видим, комитет по стандартизации С++ прилагает серьёзные усилия по работе над стандартом С++17. К концу года мы можем рассчитывать на принятие черновика этого стандарта. Разработчики чувствуют новую атмосферу перемен и это отражается в рейтингах популярности языка (в Tiobe Rank С++ набрал 8%). Термин «ренессанс С++» уже не миф…

Что ещё лучше — у нас есть множество экспериментальных фич в компиляторах. Мы уже можем экспериментировать с модулями, концептами, корутинами… Это, конечно, пока не безопасно и не может быть применено в продакшн-коде, но в плане обучения и тестирования очень интересно. Кроме того, это даёт возможность получить некоторый фидбек, который может повлиять на финальную спецификацию всех этих вещей.

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

Все компиляторы поддерживают С++11/14 на достаточно хорошем уровне, так что больше нет оправданий не переходить на использование этих стандартов. С помощью Core Guidelines данная задача становится ещё проще.

Грустные новости
Буквально пару часов назад Скотт Майерс опубликовал статью-прощание с миром С++. Обсуждение на reddit

А что вы думаете?
  • Что вам запомнилось из события около С++ в 2015-ом году?
  • Что я пропустил?


Ну и опросничек.
Какие фичи вы бы хотели непременно увидеть в С++17

Проголосовало 382 человека. Воздержалось 236 человек.

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

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


  1. leventov
    06.01.2016 13:33
    -5

    «C++ набрал серьёзную популярность в 2015» звучит неправдоподобно. Даже если он действительно таки набрал, а не растерял популярность, это единицы процентов по отношению к той популярности, которую он набрал за предыдущие десятилетия.

    Tiobe это мусорный рейтинг, в котором Go был на 49 месте (а сейчас выпал из 50, ха-ха-ха)


    1. 23derevo
      06.01.2016 16:29
      +5

      TIOBE — вполне себе рейтинг. Разве есть что-то лучше?

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


      1. mapron
        06.01.2016 20:15
        +2

        Он составляется на основе поисковых запросов, если меня память не подводит. Более-менее показывает, сколько НОВИЧКОВ начинает пользоваться языком (не очень могу представить, чтобы я начал гуглить «C++ how to remove object from vector», у меня сомнения что запросы вроде «std vector emplace_back» попадут в статистику по языку.

        «разве есть что лучше» — ну «чуть лучше» я бы назвал статистику по резюме/вакансиям с упоминанием этого языка.


      1. leventov
        06.01.2016 23:49
        -3

        «Композитные» рейтинги популярности не работают, имхо. Надо смотреть более конкретные метрики. Кол-во вакансий на hh. Кол-во вопросов (или, например, только новых вопросов) на stackoverflow. Кол-во проектов на github. И т. д.

        По Tiobe С в 6-7 раз популярнее JavaScript. При всей моей нелюбви к последнему, это не погрешность, это бред.


    1. matiouchkine
      06.01.2016 17:50
      +1

      Как составить рейтинг рейтингов?

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


  1. X_OSL
    06.01.2016 13:38

    Спасибо за обзор.
    Все-таки думаю что у С++ очень неплохие перспективы в свете падения темпов роста производительности процессоров.


  1. REU
    06.01.2016 13:50
    +4

    Поскольку язык становится богаче, современнеее (но в то же время и проще)

    Не заметил упрощения…


    1. tangro
      06.01.2016 14:41
      +11

      Ну сравните проход по std::map раньше и теперь.
      Было:

      typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
      for(it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
      {
          // do something
      }
      


      стало:

      for (auto& k : myMap) 
      {
          // do something
      }
      


      Заметили упрощения?


      1. SerCe
        06.01.2016 15:28
        +5

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


        1. stack_trace
          06.01.2016 15:39
          -8

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


          1. monah_tuk
            06.01.2016 17:20
            +8

            А кто его знает?


            1. mapron
              06.01.2016 19:39
              +1

              Рискну осторожно предположить, что Бьерни знает…


              1. IRainman
                06.01.2016 21:53
                +6

                Ну… он давал оценку своим знаниям, примерно, как 7 из 10. Честно скажу, не помню точно где я это видел, так что прошу поправить если сильно ошибся.


                1. mapron
                  07.01.2016 15:24

                  Нет, я смутно-смутно что-то такое помню, поэтому и сказал «осторожно».


            1. Bonart
              10.01.2016 15:02

              Александреску наверное…


          1. stack_trace
            07.01.2016 00:10
            -3

            Господа минусующие, можно пример кода на С++ в котором сложно разобраться? Не холивара ради, просто хочется понять — может быть, я просто слишком давно пишу на плюсах и у меня действительно «глаз замылился»?


            1. 0xd34df00d
              07.01.2016 05:11
              +4

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

              При этом я фанат плюсов, да.


            1. SerCe
              07.01.2016 12:11

              Просто случайная строчка кода из самой популярной библиотеки.
              Bind, далеко не самая страшная вещь в бусте.

              И да, это сложно, про простые вещи не пишут статей в духе «Давайте рассмотрим как заимплеменчена эта концепция через синтаксисе с++».


              1. stack_trace
                07.01.2016 17:57

                Причём здесь язык-то? Нафигачить однобуквенных аргументов можно в любом языке. Давайте быть объективными, такие строчки бывают в любых языках программирования. Внутри библиотек на джаве и питоне ещё и не такое встречается, не говоря уже про скалу. Однако, эти языки почему-то не считаются сложными. Что я упускаю?

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


                1. stack_trace
                  07.01.2016 18:04

                  Сложными для чтения, конечно же


                1. 0xd34df00d
                  07.01.2016 18:32

                  К слову о Scala, вспомнилась библиотека, с которой недавно пришлось иметь дело: биндинги к gnuplot для Haskell.

                  Совершенно недокументированная, каждый тайпкласс называется C, каждый тип данных называется T, различаются по имени модуля, их экспортирующего.


                1. SerCe
                  07.01.2016 19:22

                  Да при чем здесь однобуквенные названия? Сложность в реализации!


          1. MacIn
            07.01.2016 01:08
            +2

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

            Это фраза ни о чем. Человек говорит, что чем больше конструкций в языке (втч упрощающих жизнь), тем язык сложнее, потому что надо знать уже n+1 конструкцию для чтения кода. Вы парируете «кто знает язык, тот знает язык».
            Например — я очень редко пишу что-то на С++, при этом конструкция
            typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
            for(it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
            {
                // do something
            }
            

            нереально громоздка, но понятна любому, кто знает что-то о шаблонах (базовом элементе языка, которому 100 лет в обед).

            Конструкция
            for(auto it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
            {
                // do something
            }
            

            И проста и понятна, в том числе для тех, у кого ++ — не основной язык, потому что механика спецификатора auto прозрачна.
            А вот запись
            for (auto& k : myMap) 
            {
                // do something
            }
            

            хоть и кратка, но уже интуитивно непонятна, надо узнавать, что это за конструкция — язык стал сложнее для понимания.

            Проще для написания.
            Сложнее для понимания.


            1. stack_trace
              07.01.2016 01:18

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

              В этом плане, имхо, сложнее всего Scala, но C++ не сильно отстает.
              С тем, что язык становится сложнее спорить тяжело.


            1. 0xd34df00d
              07.01.2016 05:07

              Даже для понимания проще, если знать, что такое auto и как выводятся типы у шаблонов (а в C++ это знать всё равно надо). Просто потому, что не нужно визуально парсить все эти гроздья begin и end.

              Кроме того, range-based for loop сразу чётко даёт понять намерение кода чуть лучше, чем старый-добрый for loop. Понятно, что на каждой итерации мы всегда переходим к следующему элементу контейнера. Понятно, что мы не инвалидируем итераторы (например, не удаляем элементы из вектора или не добавляем новые). Ну и ещё что-нибудь понятно.


              1. MacIn
                07.01.2016 15:30

                Даже для понимания проще, если знать, что такое auto и как выводятся типы у шаблонов (а в C++ это знать всё равно надо).

                И об этом — второй предложенный мною вариант, а не 3й.

                Кроме того, range-based for loop сразу чётко даёт понять намерение кода чуть лучше, чем старый-добрый for loop

                Вы не поняли основную мысль.
                Разговор шел о том, что чем больше разнообразие конструкций, тем язык сложнее. Только и всего. Шаблонам — 100 лет в обед, их все знают. auto интуитивно понятен, именно поэтому второй варинат читается легко — это комбинация интуитивно понятного и старого, всем известного. А вот range синтаксис уже китайская грамота. При том, что это удобная вещь.


                1. 0xd34df00d
                  07.01.2016 18:34
                  +1

                  Ну так если б вы написали «сложнее для понимания тем, кто привык к старому C++, а на новом никогда не писал, и заодно никогда не трогал Qt с Q_FOREACH или Boost с BOOST_FOREACH», то с вами сложно было бы не согласиться.


                  1. MacIn
                    08.01.2016 00:44

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


  1. NavY
    06.01.2016 14:13

    Вообще если смотреть рейтиги TIOBE видно что рейтинг языка низок как никогда (хотя и правда сейчас на 3 месте)

    www.tiobe.com/index.php/content/paperinfo/tpci/C__.html

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

    А те кто следят за новинками языка и кому это действительно важно — те будут использовать, например Rust. Конечно остаются проблемы поддержки legacy code, но как раз для этого не так уж и важен новый стандарт.


  1. NeoCode
    06.01.2016 14:52
    +4

    Я пытался предложить улучшения в области метапрограммирования — разрешить передавать в шаблоны не только типы и целочисленные константы, но и любые другие compile-time конструкции (включая float-константы, строки и даже произвольные корректные фрагменты кода)
    К сожалению, народ на isocpp.org не поддержал.


    1. mapron
      06.01.2016 19:42

      А можно ваш proposal глянуть почитать? Особенно интересна motivation часть, конечно.


      1. IRainman
        06.01.2016 22:12

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


        1. NeoCode
          06.01.2016 22:34
          +1

          Я в основном и имел в виду унификацию. Что касается мотивации, то я особо не расписывал, т.к. реальные примеры где это нужно достаточно сложные и их сложно объяснить вне контекста реальных проектов. Но на этом и рефлексию можно сделать, и кодогенерацию, и много чего еще.


          1. mapron
            07.01.2016 15:25

            Рефлексию я не представляю, как можно через это сделать, интересно стало, можете с потолка пример как это может работать?


            1. 0xd34df00d
              07.01.2016 18:36

              Я не NeoCode, но смею предположить что-то в духе

              class Foo : public DeclareMembers<
                      void SomeFunction (),
                      std::string SomeOtherFunction (const std::string&) const
                  >
              {
              // ...
              };
              

              которое внутри развернётся в объявления функций SomeFunction, SomeOtherFunction, и регистрацию их в каком-то движке рефлексии.


    1. 0xd34df00d
      07.01.2016 05:25

      О, а поделитесь своим опытом, пожалуйста!

      Я уже джва год хочу написать пропозал, чтобы за soft errors при выводе/подстановке шаблонных аргументов принимались не только ошибки в immediate context, но и в инстанциациях всего, что участвует в immediate context, да ленюсь.

      Мотивирующе-поясняющий пример.

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


  1. kinguru
    06.01.2016 14:56
    -9

    Осталось добавить Garbage Collector и будет ещё одна Java/.NET вирт машина.
    Кстати .NET умеет собирать в нативный код (уже), т.е. работает как приложение написанное на C++.
    https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx


    1. stack_trace
      06.01.2016 15:34
      +9

      Я либо вас не понял, либо вы неправы просто-таки фундаментально.


      1. kinguru
        06.01.2016 17:17

        Я имел в виду, что в C++ появляются постепенно сахар, который уже давно есть в C# и возможно придут к Garbage Collector со временем.
        А тем временем C#/.NET идет на встречу C++ — ускоряя загрузку приложения, уменьшая потребление памяти.


        1. Zifix
          06.01.2016 17:44

          Мне представляется, что вероятность появления GC в С++ крайне мала, а вот опциональный ARC как в Objective-C может когда-нибудь и будет.


          1. DrLivesey
            06.01.2016 17:53
            +2

            Я не знаком с Objective-C но разве std::shared_ptr<T> не решает ту же задачу?


            1. Zifix
              06.01.2016 18:52

              Задача та же, но решает принципиально хуже в первую очередь потому, что писать каждый раз конструкцию уменьшающую читабельность как-то вообще не камильфо. Тут дело в другом, это решение более гибкое — если проекту нужна максимальная скорость работы, то есть возможность вообще отказаться от использования умных указателей, или применять их ограничено. Если скорость не так критична, и умные указатели используются повсеместно — то глобально включенный ARC будет эквивалентен и избавит лишних движений.

              std::shared_ptr<SomeType> someName = std::make_shared<SomeType>(constructor, parameters, here);
              
              vs
              
              SomeType *someName = new SomeType(constructor, parameters, here);
              


              1. mapron
                06.01.2016 20:19

                SomeType *someName = new SomeType(constructor, parameters, here);
                auto someName = std::make_shared(constructor, parameters, here);
                разница в 10 символов или 13%.
                Для максимальной скорости выделения памяти обычно пулы используют, либо что-то вроде placement new.


                1. Zifix
                  06.01.2016 23:22

                  • Во-первых, где в этой строчке тип указывается хоть один раз? Мне кажется что-то пропущено.
                  • Во-вторых, auto не везде разумно/возможно вставлять, в объявлении полей класса или параметров методов, их возвращаемого значения все равно нужно прописывать типы явно, так что читабельность все равно падает по сравнению с голыми указателями, число символов возрастает.
                  • В третьих несколько вариантов написания одного и того же явно избыточны, каждый будет писать как придется, опять вспоминаем про увеличивающуюся фрагментацию.


                  1. stack_trace
                    07.01.2016 00:05
                    +1

                    Насчёт конструкции, уменьшающей читабельность — спорно. Многие могут вам сказать, что явное указание, что переменная является умным указателем, повышает читабельность, ведь программисту не надо гадать, умные указатели используются в этом конкретном проекте или нет.
                    Насчёт пункта 3 — с этим приходится мириться, потому как ломать обратную совместимость никто не будет.


                    1. Zifix
                      07.01.2016 00:14

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


                      1. stack_trace
                        07.01.2016 00:56
                        +1

                        Да о том и речь, что просто посмотрев на кусочек кода/файл (например, нагуглив) нельзя точно сказать, включён он или нет.


                  1. mapron
                    07.01.2016 15:28

                    во-первых, я не посмотрел предпросмотр, и хабрапарсер зохавал шаблон. Разница в 13% в пользу new, естественно.
                    про авто — согласен, его только в таких очевидных примерах, где тип явно виден, удобно использовать (или для лямбд).
                    3) — тут не поспоришь.


              1. IRainman
                06.01.2016 22:49
                -1

                Дополню mapron поскольку использовать new и delete не безопасно, впрочем как и сырые указатели, а с C++14 это окончательно пофикшено и в общем случае следует использовать unique_ptr вместе с make_unique так что разница в написании вообще нулевая.

                P.S. на всякий случай напоминаю всем разработчикам на C++, что unique_ptr+make_unique фактически является синтаксическим сахаром и не привносит дополнительных накладных расходов при сравнении с сырыми указателями и использованием new+delete, однако его использование гораздо более безопасно из-за особенностей генерируемого кода, впрочем как и из-за отсутствия необходимости явного вызова delete, в котором помимо явной утечки в случае exception перед ним можно ещё ошибиться из-за [] в случае массива (неважно при каких условиях, факт в том, что можно). Ошибку же с использованием new+delete можно отловить только при анализе утечек памяти при завершении работы приложения в рантайме либо грубые ошибки (массив — единичный элемент в случае delete) некоторыми статическими анализаторами.

                P.P.S. я понимаю о чём вы говорите и что можно сделать синтаксис проще, но для этого, учитывая концепцию C++ надо будет однозначно вводить специальную директиву, отключающую обратную совместимость и это касается не только new, но и многого другого из «наследия прошлого». Наверняка после введения модулей такую директиву сделают, чтобы в пределах модуля использовать канонический C++ с обратной совместимостью, а вне его пределов уже современную на тот момент версию языка. Но это пока только мысли на будущее ибо требует очень большой работы от разработчиков компиляторов, а пока уж как есть ибо и так изменений огромное количество и для авторов компиляторов и для разработчиков на языке.


                1. Zifix
                  07.01.2016 00:34

                  поскольку использовать new и delete не безопасно, впрочем как и сырые указатели
                  Ну вы нашли, чем плюсовика напугать:
                  «Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво» Брайан Керниган
                  Если серьезно, то нулевая разница только по сравнению с shared_ptr, пример же приведен для сравнения с ARC, и unique_ptr тут картину не улучшает. Но в целом замечание ценное, спасибо.


                  1. IRainman
                    07.01.2016 03:03

                    Ну вы нашли, чем плюсовика напугать

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

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

                    P.S. всегда пожалуйста ибо просто стараюсь поднимать относительно сложные вопросы, до обсуждения которых обычно не доходят в дискуссиях.

                    P.P.S. у меня ещё просто профориентация на проекты, которые должны очень долго работать и быть максимально надёжны, так что некоторая паранойя в этой области тоже есть, не скрою :) Вообще мне для заверения треда уж очень хочется пригласить к обсуждению Andrey2008 ибо он как один из разработчиков хорошего (по моему опыту) статического анализатора, наверняка, может ткнуть в годные примеры, где в известных и используемых многими проектах использование new/delete, включая ошибки с оператором [], да ещё и голое их использование без обвёртки без соблюдения принципа RAII приводило к утечкам, порчи памяти и другим «радостям».


                    1. Andrey2008
                      09.01.2016 16:38

                      Да, таких ошибок много. Однако у меня нет какого-то конкретного мнения, как сделать мир лучше.

                      Кстати, можно напортачить c [] не только при использовании голых new/deletе, но и применяя умные указатели.


                      1. IRainman
                        10.01.2016 01:39

                        Да, вот и я не знаю как побороть проблему на корню. С auto_ptr всё уже давно понятно, благо он deprecated с C++11, а с C++17 вообще будет удалён.


                      1. vladon
                        11.01.2016 20:04
                        +1

                        `auto_ptr` не умный, а так себе указатель.


                1. 0xd34df00d
                  07.01.2016 05:27

                  впрочем как и сырые указатели

                  Сырые указатели вполне себе нормальны и представляют семантику «передать в функцию указатель на объект, не передавая владение».
                  unique_ptr — передаёт владение, и вызывающий код его теряет.
                  shared_ptr — разделяет владение, что не всегда корректно и не всегда является подразумевавшимся намерением.


                  1. IRainman
                    07.01.2016 05:52

                    В функции unique_ptr можно ведь и ссылкой передавать. Для shared_ptr есть ещё weak_ptr без передачи владения.

                    Безусловно сырые указатели нормальны, просто я к тому, что в современным C++ есть много хорошего, что позволяет исключить много опасных вещей из кода.

                    Пожалуй самое главное замечание на счёт умных и сырых указателей: не стоит мешать их вместе для одного объекта ибо этим можно создать себе дополнительные и особенно экзотические проблемы.


                    1. 0xd34df00d
                      08.01.2016 02:22
                      +1

                      В функции unique_ptr можно ведь и ссылкой передавать. Для shared_ptr есть ещё weak_ptr без передачи владения.

                      Это делает ваши функции менее универсальными. Если вы написали, что функция принимает unique_ptr по ссылке, то указатель на объект на стеке, например, вы уже не передадите. Если вы написали, что функция принимает weak_ptr, то указатель на объект на стеке вы уже не передадите (без особых костылей). Зачем такие ограничения, если всё, что нужно функции — указатель на объект, и её требование — чтобы объект был жив всё время работы функции, и не более, а об особенностях жизни объекта вне неё она не заботится и не должна?

                      Безусловно сырые указатели нормальны, просто я к тому, что в современным C++ есть много хорошего, что позволяет исключить много опасных вещей из кода.

                      ИМХО единственное, что в контексте памяти опасно — явные new и delete. Вот их надо стараться всяко исключать, да.


                      1. IRainman
                        08.01.2016 18:05

                        Да, вы правы. С меньшей универсальностью полностью согласен. Также и с тем, что самое опасное это явные new и delete.


              1. Chaos_Optima
                11.01.2016 14:35

                При помощи лёгкого макроса и маленькой шаблонной функции можно превратить это

                std::shared_ptr<SomeType> someName = std::make_shared<SomeType>(constructor, parameters, here);
                
                в это
                
                auto someName = share new SomeType(constructor, parameters, here);
                


    1. victorv
      06.01.2016 17:05

      Кстати .NET умеет собирать в нативный код (уже)

      Подобные попытки предпринимались неоднократно и многими. Особенно на ранних стадиях развития виртуальных сред исполнения. Вот только один пример для Java среды: https://gcc.gnu.org/java/
      Однако приоритет развития был всё-таки отдан «компиляции на лету» (англ. Just-in-time (JIT) compilation).


      1. kinguru
        06.01.2016 17:23

        Это не попытка, это готовый продукт. Использовать или нет решайте сами.


    1. BalinTomsk
      06.01.2016 20:05

      Да нy нету? C++/CLI для любителей GC.


      1. maydjin
        07.01.2016 00:07
        +1

        Там для GC свой тип ссылок и указателей и свой оператор new. managed c++ это редкий уродец с каким то зашкаливающим количеством возможных ссылок на обьекты, сделанный как мне видится, исключительно для написания производительных биндингов в .Net с сабжа и сишечки.

        А, да, там ещё два типа шаблонов, с интересными правилами взаимопременения :)

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


  1. Zifix
    06.01.2016 15:24
    +16

    Боюсь показаться ретроградом в треде про С++17, но господа, не слишком ли много мы получили? Если раньше разговоры про то, что никто не знает С++ полностью были шутками, то теперь это реальная ситуация. Других языков, которые бы так быстро и решительно насыщали фичами я не знаю. В итоге мы оказываемся в ситуации, когда каждый знает и/или использует какое-то свое подмножество, из-за чего язык перестает быть универсальным, разбираться в чужом коде становится гораздо сложнее. И это я еще молчу о злоупотреблении фичами из серии «потому что могу» и «эту я еще не пробовал».


    1. stack_trace
      06.01.2016 15:37
      -4

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


      1. 0xd34df00d
        07.01.2016 05:30
        +1

        move-семантика и всё с ней связанное, как показывает практика, оказывается сложным для восприятия.

        И это я ещё не говорил о наконец-то появившейся многопоточности в стандарте, со всеми вариантами sequential consistency, например.


    1. Daffodil
      06.01.2016 19:48
      +5

      Проблема в том что C++ спал летаргическим сном с 1998 года до C++2011, в то время как остальные языки постоянно насыщялись удобными фичами. Поэтому теперь приходится наверстывать.


      1. evocatus
        07.01.2016 05:15

        И появились вещи типа Qt (где написали свои библиотеки для всего и оно теперь как-то должно существовать параллельно с этими С++1Х, а Qt используют многие)


        1. 0xd34df00d
          07.01.2016 05:29

          И при этом сосуществует оно местами из рук вон плохо. QtConcurrent::mapped в 2016 году не умеет выводить тип возвращаемого значения из лямбды, приходится оборачивать в std::function, например.


          1. Zifix
            07.01.2016 09:10

            Идеального нет, но в целом для работы с Qt требуется очень небольшое и прозрачное подмножество языка без магии и неоднозначностей, сигналы-слоты опускают порог вхождения даже в многопоточное программирование, из-за чего С++03 подтягивается до уровня современного языка. Это я не говорю о средствах работы с сетью, файловой системой, и т.д. что в официальном стандарте только в планах.


            1. 0xd34df00d
              07.01.2016 15:21

              сигналы-слоты опускают порог вхождения даже в многопоточное программирование

              Опыт сидения в паре XMPP-конференций и наблюдения за вопросами показывает, что не очень.

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


    1. QtRoS
      07.01.2016 00:11
      +1

      то теперь это реальная ситуация

      Да, это уж точно — я преимущественно на C# специализируюсь, и поддерживать знание C++ "в фоне" становится все сложнее и сложнее. Благо моя сфера интересов, связанная с C++, в основном Qt\QML касается, а там более или менее свои законы и устоявшиеся идеологии.


    1. Yuuri
      07.01.2016 00:57

      Других языков, которые бы так быстро и решительно насыщали фичами я не знаю.

      C# регулярно обрастает ими прямо-таки с космической скоростью.


    1. BalinTomsk
      11.01.2016 02:12
      -2

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

      Жаль что убрали.


      1. Chaos_Optima
        11.01.2016 11:56
        +1

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


  1. DanmerZ
    06.01.2016 17:53
    +3

    Придётся ждать C++: The Good Parts



  1. Daffodil
    06.01.2016 19:43
    +3

    А compile-time интроспекцию так и не сделали. Придется по-старинке лютым копипастом сериализацию/десериализацию делать.


    1. IRainman
      07.01.2016 03:23
      +1

      Даа уж, у меня в подобных особо тяжёлых случаях частенько вообще кодогенерация на макросах #жизнь-боооль.

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

      Когда активно участвовал в проекте FlylinkDC++ то масштабно занимался рефакторингом, в т.ч. гуйной части и там для унификации менюшек и много чего ещё это было нужно, даже вопрос на тостере тогда задал, благо что конкретно в этом случае у Visual Studio оказался специальная конструкция __if_exists благодаря которой в этом случае удалось всё унифицировать «малой кровью».


  1. NeoCode
    06.01.2016 21:26

    Кстати, у меня такое чувство что предлагаемый «оператор точка» это что-то очень близкое к «свойствам» (properties), которые есть во многих языках. Только более общее: если свойства определяют геттеры и сеттеры для полей класса, то «точка» — геттер и сеттер (одновременно? или можно развести их через const?) для всего объекта класса сразу.


    1. vladon
      11.01.2016 20:07

      плюс ещё проще писать паттерн прокси


  1. emusic
    13.01.2016 14:41
    +1

    Таки не «корутины», а сопрограммы. :) Термин прижился в русском языке много лет назад. :)


  1. emusic
    13.01.2016 14:50

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

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


    1. MacIn
      14.01.2016 00:14

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

      Например, как вы это видите?


      1. emusic
        14.01.2016 06:22

        В простейшем случае — примерно так:

        // Функция, вызываемая на известном уровне приоритета

        F1 (...) _attrval (Level = 2) {… }

        // Функция, вызов которой допустим только на определенных уровнях приоритета

        F2 (...) _attrcond (Level <= 1) {… }

        Значение атрибута Level, заданное для F1, распространяется на все функции, явно вызываемые из нее. Если на этом пути вдруг встретится вызов F2 — у компилятора будет возможность выдать предупреждение, и не потребуется писать тесты для всех возможных путей вызова F2.

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

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

        Смысл в этом примерно тот же, что и у константных объектов/методов, только в дополнение к константности вводятся дополнительные атрибуты объекта/функции.