Без new: Указатели будут удалены из C++

http://www.modernescpp.com/index.php/no-new-new
  • Перевод

Две недели назад в Джэксонвилле встречался комитет стандарта ISO C++. Сегодня я хочу представить короткую сводку и написать о революционном решении, принятом на собрании в Джэксонвилле. Для получения дополнительной информации я рекомендую к прочтению статью C++ больше не будет иметь указатели. Комитет по стандартизации языка принял решение о том, что указатели будут объявлены устаревшими в C++20 и с большой долей вероятности будут удалены из C++23.


Откровенно говоря, то, что кажется революционном, — всего лишь последний шаг длинной эволюции.


image

Эволюция указателей в C++


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


В C++98 мы получили std::auto_ptr для выражения исключительного владения. Но std::auto_ptr имел большой изъян. Когда вы копирует std::auto_ptr, владение ресурсом передавалось копии. Копирование выглядело как перемещение. Изображение ниже показывает неприятное поведение std::auto_ptr.
image


Это было очень плохо, приводило к множеству серьёзных багов. Поэтому мы получили std::unique_ptr в C++11, и объявили std::auto_ptr устаревшим в C++11, и окончательно удалили из C++17. Дополнительно мы получили std::shared_ptr и std::weak_ptr в C++11 для управления владением. Вы не можете копировать, но можете перемещать std::unique_ptr, и если копируете или присваиваете std::shared_ptr, счётчик ссылающихся указателей увеличивается. Посмотрите сюда:
image


Начиная с C++11 C++ имеет многопоточную библиотеку. Это делает управление std::shared_ptr достаточно сложным, потому что std::shared_ptr по определению разделяемое, но не потоко-безопасное. Только контрольная часть со счётчиками является потоко-безопасной, но не доступ к адресу контролируемого ресурса. Это значит, что изменение счётчика — атомарная операция, но вы не имеете гарантии, что ресурс будет удалён ровно один раз. По этой причине мы получаем в C++20 атомарные умные указатели: std::atomic_shared_ptr и std::atmic_weak_ptr. Про детали предложений комитета стандартизации читайте здесь: Атомарные умные указатели.


Теперь переходим к более интересным частям будущих стандартов C++20 и C++23. Указатели будет объявлены устаревшими в C++20 и удалены из C++23. Скажем три слова: Нет Новому New (NNN).


std::unique_ptr спасёт нас


Но подождите, как же догма C++: Не платить за то, что вам не нужно. Как мы сможем программировать без указателей? Просто используйте std::unique_ptr. Из своего дизайна std::unique_ptr такой же быстрый и экономный, как и обычный указатель, и имеет явное преимущество — автоматическое управление ресурсом.


Ниже простой тест производительности.


// all.cpp

#include <chrono>
#include <iostream>

static const long long numInt= 100000000;

int main(){
  auto start = std::chrono::system_clock::now();

  for ( long long i=0 ; i < numInt; ++i){
    int* tmp(new int(i));
    delete tmp;
    // std::shared_ptr<int> tmp(new int(i));
    // std::shared_ptr<int> tmp(std::make_shared<int>(i));
    // std::unique_ptr<int> tmp(new int(i));
    // std::unique_ptr<int> tmp(std::make_unique<int>(i));
  }

  std::chrono::duration<double> dur= std::chrono::system_clock::now() - start;
  std::cout << "time native: " << dur.count() << " seconds" << std::endl;
}

Эта программа выделяет и освобождает память для 100 миллионов int. Я использую указатели, std::shared_ptr и std::unique_ptr в двух вариациях. Я компилирую программу с и без максимальной оптимизации в Linux и в Windows. Получаются такие числа:
image


Две вариации std::unique_ptr на Linux и Windows показывают такую же производительность, как обычные указатели. За деталями этого теста обратитесь к моей прошлой статье: Потребление памяти и производительность умных указателей.


Семантика владения


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


  • Локальные объекты. Рантайм C++ как владелец автоматически управляет жизнью таких ресурсов. То же самое относится к глобальным объектам или членам класса. Справочники сводят это к области видимости.
  • Ссылки: я не владелец. Я только обеспечиваю, что ресурс не может быть пустым.
  • Обычные указатели: я не владелец. Я только ссылаюсь на ресурс, если он есть. Я не должен удалять ресурс.
  • std::unique_ptr: я исключительный владелец ресурса. Я могу явно освободить мой ресурс.
  • std::shared_ptr: я разделяю ресурс с другими std::shared_ptr. Я могу явно удалить мой разделяемый ресурс, если он больше никому не нужен.
  • std::weak_ptr: я не владелец ресурса, но я могу временно разделять ресурс при вызове моего метода std::weak_ptr::lock.

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

Поделиться публикацией
Комментарии 150
    –33

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


    Я не понимаю, почему комитет не задеприкейтит создание новых проектов на этом языке в пользу Раста, у которого эти проблемы были решены 5 лет назад. Наконец-то подход комитета С++ потихоньку начинает понимать проблематику и то, как это стоило бы решать в нормальных условиях. Но он решает проблему дат и файловой системы.

      +21
      Обещаете лично перевести на раст миллиарды строк легаси?
        –23

        А кроме огромной кодовой базы (читай легаси кода), есть хоть какой-то смысл использовать C++ вместо Rust?

          +38
          А кроме следования веяниям моды, есть хоть какой-то смысл использовать Rust вместо C++?
            –3
            На самом деле, похоже, есть. В частности то, что указателей в смысле C++ нету — это плюсик. Язык молодой, необкатанный, но за ним уже пора следить…

            Как в конце 80х все массово перешли с Паскаля на C (вы в курсе, что изначально и MacOS и Windows на Pascal были написаны?), так и тут может произойти через 30 лет…
              +9
              MacOS и Windows на Pascal были написаны?


              Windows не была. И даже DOS не был. До версии 3.0 он был полностью написан на ассемблере. В 3.0 attrib.exe стал первой утилитой на C. Постепенно весь DOS был переписан на C. WinAPI 16 использовал соглашение вызовов __pascal ради экономии двух байт на стеке и того, что такой вызов был чуть быстрее. Что было важно для машин с десятками килобайт памяти и единицами мегагерц скорости.

              Но свои версии компиляторов Pascal Microsoft делал до конца 80-х.
                –12
                То, что Windows была написана на Паскале легко понять, если немного думалку включить.

                1. Компилятор Microsoft Pascal 1.10 — это 1981й год.
                2. Первый компилятор C для IBM PC, Lattice C — это 1982й год.
                3. Microsoft C 2.0 — это всё тот же самый Lattice C под другим брендом, только вышел он в 1984м.

                Так на каком языке была написана Windows, если работа над ней началась в 1981м, а в 1983м безумный Стив Баллмер (которому пообещали, что «усё будет готово к 1983му и „наивный чукотский вьюноша“ поверил) устроил в Лас-Вегасе охренительную рекламу Windows (продукта, который не выйдет на рынок ещё два года)?

                Другое дело, что до релиза эта версия (в отличие от MacOS) не добралась… это да — но изначально она писалась на смеси Assembler'а (без этого ни одна OS не обходится, вопрос лишь в пропорциях) и Pascal'я…
                  +3
                  Другое дело, что до релиза эта версия (в отличие от MacOS) не добралась… это да — но изначально она писалась на смеси Assembler'а (без этого ни одна OS не обходится, вопрос лишь в пропорциях) и Pascal'я…

                  Так первая Windows по вашему мнению была написана, или же был написан некий не увидевший свет концепт?
                    +4
                    Windows 1.x как и ранние DOS была написана на ассемблере. Только с 2.0 появился код на C. В общем-то для начала 80-х это было нормой. Домашние пользователи могли писать хоть на бейсике, но те, кто поставлял им систему вынуждены были выжимать из компа всё.
                  +3
                  Offtop: можно поподробнее про Windows на паскале? В Википедии про версию 1.01 сказано, что 85% C, остальное ассемблер. Больше ничего нагуглить не смог.
                    +3
                    Этот миф ходит из-за того, что у WinAPI 16 было соглашение вызовов __pascal. Люди игнорируют что в начале 80-х это было самое популярное соглашение вызовов (причины написаны выше) и думают, что раз есть слово «паскаль», то и написано на нём было. А вот старый Mac OS, до десятки и правда на Pascal был.
                  +5
                  • Мощная система типов унаследованная от Haskell вместо ООП + аффинные типы и следующие из них статические гарантии(memory safety, fearless concurency, итп итд)
                  • Модули
                  • Стандартный пакетный менеджер вместо зоопарка несовместимых друг с другом решений
                  • Стратегия развития языка(эпохи, RFC, вот это вот всё)
                  • Синтаксис и стандартная библиотека без груза многолетней поддержки обратной совместимости
                  • Синтаксическое разделение языка на safe и unsafe подмножества, которое позволяет легко определить где в коде используется чорная магия и прочее колдунство)

                  И это только то, что сразу на ум пришло.

                    +3
                    Забыли отвратительный синтаксис (ИМХО, конечно).
                      +5
                      Лучше чем у C++.
                        +2
                        не «забыли», а «не взяли».
                      +6
                      Ну, во первых, это всё равно недораст получается. И превратить C++ в Rust никаким напильником не выйдет. Хотя бы потому, что указатели далеко не единственная проблема.

                      А что касается легаси, то он никуда не денется. И принятие нового стандарта не превратит автоматически «8.5 миллионов строк C++ кода» хромиума в C++ код стандарта C++23.
                        +1
                        Хромиум — неудачный пример. Код там вполне современный
                          0
                          Именно, что современный. Не C++23. Впрочем, похоже всё это оказалось качественным розыгрышем.
                          0
                          Если вы считаете указатели проблемой — да, лучше пишите на Rust, С++ не для вас. Это не делает его плохим языком. Это всего лишь делает вас некомпетентным программистом на С++.
                            +1
                            В каждой статье про плюсы когда говорят про плюсы всегда появляются «Ненастоящие шотландцы», которые все делают неправильно. Плохой язык — тот, в котором легко допустить ошибку, которую легко могут предотвратить средства оптимизации, в данном случае — компилятор, хорошие — в котором это сделать сложно. От «правильного» или «неправильного» разработчика тут ничего не зависит, это свойство языка, а не конкретного человека.

                            Указатели мощная концепция, которая почти всегда не нужна, ибо ссылки практически все сценарии поддерживают лучше. Для оставшихся редких задач да, можно использовать указатели, и пометить соответствующие блоки типа «beware, here be dragons».
                              –4

                              До тех пор, пока в Rust присутствует unsafe блок, комментарий про некомпетентных программистов является справедливым.

                                +4
                                А можно определение «некометентности», пожалуйста? А то я полагаю, что у вас это «тот кто хоть раз в жизни делал double free и out of bounds access», подо что попадают все программисты планеты.
                                  –2
                                  Ошибки в double free, out of bounds или делении на 0 вполне вероятны по невнимательности. Моя мысль в том, что пока в языке (любом) есть способ прострелить себе ногу (даже самый изощренный), люди будут это делать.

                                  Я не согласен только с вашим определением «плохого языка», оно слишком категорично. Я не люблю называть языки, которые могут как-то приносить пользу, плохими. Возможно, я через чур оптимистичен.
                                    +2
                                    Мое мнение таково: если у нас есть равномощные (не в плане Тьюринг полноты, а в естественном смысле) языки, но в языке А способ прострелить себе ногу изощренный, а в Б — нет, то А лучше Б. Это собственно практическое применение принципа Паретто: если у нас есть множество альтернатив (в данном случае А и Б), и А не хуже Б по всем критериям, но лучше по хотя бы одному, то А — предпочтительная альтернатива.
                                      +1
                                      Я согласен, что в данном случае А лучше Б, но Б не является плохим только по этому признаку.

                                      Возможно, вы не правильно поняли меня про некомпетентность, я имел в виду не вас, а то, что всегда будут некомпетентные люди для любого языка, где есть такая возможность.
                                        0
                                        You Can Write FORTRAN in any Language
                                +1
                                средний программист не вчера универ закончил, а полгода работы уже более чем достаточно научиться работать с памятью в современных плюсах. Вон в go, например, весь упор был на надежность, ради которой пожертвовали лаконичностью. Rust построен на принципе «явное лучше неявного», а я например считаю, что излишняя явность перегружает код второстепенными вещами — его проще писать, но сложнее читать. А читается код чаще.
                                  +3
                                  средний программист не вчера универ закончил, а полгода работы уже более чем достаточно научиться работать с памятью в современных плюсах.


                                  конечно научился, а то бы у него программы падали постоянно.
                                  но есть такой фактор как невнимательность.
                                  невозможно 100% времени быть 100% сконцентрированным.

                                  и главное — зачем?
                                  если можно это перепоручить компилятору.
                                    0
                                    и что, программисты по невнимательности пишут new вместо make_shared?

                                    Сконцентрированным быть всё равно придется, ибо большая часть ошибок — логические. Их зачастую куда дольше ловить и куда сложнее исправлять.
                              0
                              В Хромиуме (точнее, в Блинке) умные указатели были еще до того, как они приобрели нынешний вид в современных стандартах C++.
                              А некоторое время назад они наоборот отказались от умных указателей в пользу сборщика мусора.

                              И да, кодовая база по-тихоньку, но рефакторится на C++11/C++14.
                            +5
                            А кроме огромной кодовой базы (читай легаси кода)

                            А этого мало?
                            • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              В одном хромиуме 8.5 миллионов строк C++ кода.
                                0
                                Кстати firefox же работает на rust и c++ и работает он быстрее хрома, особенно на ресурсах кровавого интерпрайза
                                  +8
                                  А edge бывает и быстрее. И ресурсов не жрёт много и раста там нет.
                                    +1
                                    К тому же, раньше FF был на C++ и тормозил вообще безбожно. Им вон даже новый язык пришлось придумывать, чтобы заработало прилично. Так что это от программиста зависит, как оно работать будет.
                                      –2
                                      Если те же программисты перейдя на новый язык смогли написать FF, который перестал безбожно тормозить, то может это и есть показатель того, что смысл в расте есть?
                                        +2
                                        Для них — да и для тех кому нравится да.
                                          –1
                                          При чем тут нравится или нет? Это все равно, что купил монитор побольше или кресло поудобнее — и разработчик стал сразу эффективнее писать. Это вполне объективный показатель. Был разработчик на плюсах, имел такую-то эффективность. Ему дали раст, он стал писать лучше. Берем теперь кучу таких разработчиков, и получаем вполне себе адекватную метрику.
                                            +13
                                            Пост про C++ я не про раст — вот причём. В каждый пост про С++ приходят фанаты раста и начинают объяснять как «правильно» надо программировать.
                                              –3
                                              Это печально, но при чем тут это? Да приходят, но мы вроде другое обсуждали.
                                              +1
                                              Скорее не так:
                                              Была куча программистов на С++, которые тянули старый код годами.
                                              Наняли новых (часть, конечно, переучили) и сделали глобальный рефакторинг.

                                              И совсем не факт, что если бы наняли хороших архитекторов и потратили то-же время на рефакторинг получилось бы хуже.
                                              Хром то, на C++ и не тормозит.
                                            +4
                                            Он перестал тормозить из-за того, что некоторый устаревший код не выполняется. Программа работает не в сферическом вакууме, а в многозадачных ОС, у которых есть оптимизаторы выполнения (к примеру, префетчер в Windows, в Linux это реализовано по-другому, но конечный результат тот же). Оптимизаторы выполнения работают в парадигме «Быстрая память – дефицитный ресурс для всех запущенных процессов», поэтому они и не загружают в ОЗУ те участки кода, которые никогда не будут выполняться (либо сбрасывают их на диск, чтобы освободить ОЗУ). И оптимизатору выполнения все равно на каком языке была написана программа, здесь в первую роль играет компилятор, а не язык. Поэтому выдавать ускорение быстродействия за преимущество, полученное из-за перехода на какой-либо новый язык программирования, мягко говоря, некорректно.
                                              +2
                                              Язык вполне может влиять на это. Никто же не сомневается, что наличие типов позволяет оптимизировать намного агрессивнее плюсовому компилятору, чем например JS-овскому? Если гооврить про плюсы, то такой гарантией может быть классический пример:
                                              void copy(int* src, int* dest, int size) {
                                                  for(int i=0;i<size;++i) {
                                                      array[i] = dest[i];
                                                  }
                                              }

                                              Из-за стандарта плюсы обязаны производить лишние операции в цикле, чтобы соблюсти правила алиасинга. Хотя передавать одну и ту же ссылку (или даже пересекающиеся) в src и dst это явно автор не предполагал. Но если поставить __restrict__, то основной кейз становится таким же быстрым, но теперь в случае нарушение гарантий (кто-то случайно не то передал) последствия могут быть намного хуже.

                                              Собственно, тезис простой и думаю вы с ним согласны: чем сильнее система типов, тем больше простор действий для оптимизатора. Тут вот небольшая заметка в качестве примера, как это происходит по шагам. Можете описать, согласны ли вы с выводами?
                                                –4
                                                Во всех вменяемых компиляторах включенная оптимизация дальше базовой по дефолту отключает эту проверку.
                                                  +2
                                                  Ни один оптимизатор не имеет права нарушать стандарт, это известно каждому. Никому не нужен быстрый некорректный код.
                                                    0
                                                    По стандарту нарушение aliasing — undefined behaviour, следовательно компилятор имеет право делать что угодно
                                                      0

                                                      А зачем вам быстрый некорректный код, когда существующая система типов в Раст позволяет вам написать такой же быстрый код, но при этом корректный? Что мешает лично вам?

                                                        –2
                                                        Некорректный код пишет программист по своей глупости, и язык в этом не виноват. Если он не знает правил языка, на котором пишет — он профнепрегоден и при первом же таком косяке должен быть уволен по статье
                                                          +4
                                                          Видимо, команды таких проектов, как Chromium/FF/MySQL/Postgress/younameit надо давно разогнать, ибо в том же блоге PVS Studio каждую неделю выходит статья с целой пачкой найденых багов.

                                                          Ошибки совершают все, даже люди с 20-летним стажем. В любом языке. Но, может, лучше возложить часть нагрузки на язык, а не сваливать всю вину на программиста?
                                                            0

                                                            Всегда на такие "фразочки" отвечают: а покажите свой гитхаб. Более чем уверен, что если вы написали пару тысяч строк кода на С++, я найду в них багу. Ну-ка, товарищ, вперед!

                                                          +1
                                                          Где именно в этом коде нарушение aliasing?
                                                            0
                                                            В этом коде его и нет, и его поведение defined не зависимо от того, перекрываются ли области по этим указателям или нет.
                                                              +1
                                                              Именно так и есть. Поэтому оптимизатор ни с какими ключами не сможет ничего толком ускорить.
                                                        0
                                                        ссылку бы на godbolt, иллюстрирующую тезис
                                                        0
                                                        Я приведу иллюстрацию к своему сообщению.
                                                        Есть программа SphericalCowCAD. В этой программе есть функции Foo(x) и Bar(y). Функция Foo вызывается в M*N раз чаще (M>>0, N>>0) функции Bar. Оптимизатор многозадачной ОС исключает (в соответствии с парадигмой дефицита быстрой памяти) загрузку функции Bar из медленной долговременной памяти в быструю память. Вопрос: на каком языке программирования написана программа SphericalCowCAD?
                                                          0
                                                          Несколько вопросов по коду.
                                                          1. Зачем вы передаёте указатель src, если потом не используете его?
                                                          2. Откуда взялся array? Это глобальная переменная?
                                                          3. Почему читаются значения из dest, когда по смыслу это место куда надо копировать, а не откуда?
                                                          Отсутствие проверки src и dest на null, и на равенство друг другу можно списать на то что это просто пример. Но в целом по коду вообще не понятно что он должен делать, и что вы хотите показать. Это выглядит как бессмыслица. Могу лишь предположить, что вы случайно запостили результат нескольких несогласованных между собой правок кода.
                                                            +2
                                                            Прошу простить, редактировал в последние секунды сообщение и не успел все поправить. Должно выглядеть это примерно так:

                                                            void copy(int* src, int* dest, int size) {
                                                                for(int i=0;i<size;++i) {
                                                                    dest[i] = src[i];
                                                                }
                                                            }
                                                        +1
                                                        а вы часто рефакторите код так, чтобы он стал хуже?
                                                          +1
                                                          А это делали одни и те же программисты? не думаю, что вся команда бросила плюсы и переучилась на раст.
                                                          Да, в плюсах 1000 и 1 способ выстрелить себе в ногу, но в умелых руках и при должной осторожности можно делать действительно классные и быстрые вещи, например полноценный паттерн «состояние» на стеке
                                                            +1
                                                            Вполне допускаю, что делали одни и те же. В конце концов, авторы раста до того как появился раст писали скорее всего именно на плюсах, и именно на него ориентировались при его создании. И уж точно неоткуда было взяться растопрограммистам с опытом кроме как просто перевести кого-то из команды изнутри.

                                                            Насчет классных вещей — совсем не спорю. Есть языки, которые безопасны и там нельзя этого сделать — управляемые джавы и шарпы из таких. Есть плюсы где это можно сделать, но с безопасностью есть определенные проблемы. Раст на моей памяти первая удачная с моей точки зрения попытка усидеть на двух стульях. Более строгий анализатор с возможностью отключения проверок в некоторых местах (с явной аннотацией «я думаю тут все в порядке, но кто знает») мне кажется более продуктивен для разработчика, чем менее строгий. В конце концов всякие статические анализаторы для плюсов для того и придумали. Просто оказывается, что если запретить некоторые корректные, но сложноанализируемые вещи то анализатор становится намного полезнее. И пусть эти корректные вещи приходится либо переписывать так, чтобы уговорить компилятор пропустить их, либо воспользоваться unsafe. Но ведь во всем остальном проекте он будет помогать, а не мешать.

                                                            Я буквально на днях писал пример для интервью в одну компанию на расте. Писал часов 10, исправляя ошибки, в конце концов оно скомпилировалось. И это было бесподобно, потому что на моих ежедневных шарпах такого бы точно не произошло — NullRef где-нибудь или выход за границы массива — гарантированно. До этого у меня такое было всего один раз, когда я изучал хаскель. Там тоже происходит долгий диалог с анализатором, в конце которого получается рабочий продукт. Как по мне, это намного приятнее, чем сидеть с дебаггером.
                                                              0

                                                              Выход за границы на шарпе? Интересный вы код пишете, если не ходите по массиву, а вычисляется значения индексов на лету.
                                                              Ну и не помню когда вообще последний раз ловил npe.
                                                              А что это за тестовое, которое надо фигачить 10 часов? Можете в двух словах рассказать?

                                                                0
                                                                IndexOutOfRange — действительно редкий гость, но иногда случается, особенно при работе со строками: string.Remove, string.Substring, вот это все.

                                                                Что касается NRE — просто с трудом могу поверить, что есть человек, который с ними редко сталкивается. Наряду с KeyNotFoundException это самые противные исключения, контекст которых абсолютно непонятен, и которые просто являются бичом.

                                                                Что касается тестового: там просто поиск на графе, просто исполнение осложнялось несколькими условиями. Во-первых я писал на языке, который начал изучать в конце прошлого года серьезно, когда IDE наконец начали нормально работать. Во-вторых я плохо знаком с алгоритмами на графах, и например я долго думал об алгоритме упаковки матрицы в вектор так, чтобы при ресайзе не нужно было ничего копировать поэлементно (вот мой вариант, с которым мне кстати еще и помогли, если есть идеи, как улучшить — welcome). Ну и в-третьих в задании просили писать production-ready код, поэтому сюда добавляется время на тесты, XML-доки и вот это все.
                                                          0
                                                          FF тормозил не потому, что C++, а потому, что XUL и однопоточный
                                                            +2
                                                            Правильно, и попытки сделать его многопоточным предпринимались неоднократно, и неоднократно же проваливались. Силами, скажем так, далеко не последних разработчиков. А Stylo на Rust сделался с первого раза.
                                                              0
                                                              А Stylo на Rust сделался с первого раза.


                                                              Вы так легко пишете «с первого раза»… а ведь целый Rust был создан.

                                                              предпринимались неоднократно


                                                              Попытки уровня «Взять и переписать с нуля»?
                                                                0
                                                                Вы так легко пишете «с первого раза»… а ведь целый Rust был создан.
                                                                Rust разрабатывался задолго до того, как автора наняло Mozilla Foundation.
                                                                Попытки уровня «Взять и переписать с нуля»?
                                                                Не думаю. А что, так нечестно?
                                                                  0
                                                                  Rust разрабатывался задолго до того


                                                                  Лейте в уши дальше.
                                                                  Rust уже под крылом Мозиллы пережил кучу серьезных изменений.
                                                                  0
                                                                  Вы так легко пишете «с первого раза»… а ведь целый Rust был создан.

                                                                  Да, был. Именно потому что на нем эта задача оказалась проще.

                                                                    0
                                                                    Там не в rust'е дело, а в том, что расширения нельзя поддержать. Вот когда они решились на то, чтобы перестать их поддерживать — оно и стало возможным. А rust тут вообще никаким боком не замешан.
                                                                      0

                                                                      Про fearless concurrency не слышали? Без Rust такой подход невозможен.

                                                                        +1
                                                                        Я много про что слышал. Но это не меняет того факта, что в Firefox 54 кода на rust'е не так что уж очень сильно много всего было — а многопоточность уже была.

                                                                        Да, сейчас уже больше компонент из Servo втащили, что неплохо, но собственно многопоточность rust'а не требовала.

                                                                        P.S. И ещё раз, я не против rust'а. Интересный эксперимент. Я против утверждений «без rust'а вы не сможете сделать XXX». Сможете. Вопрос в цене.
                                                                          +1
                                                                          С другой стороны, при ограниченном бюджете «вопрос в цене» иногда является синонимом для «не сможете сделать».
                                                                            0
                                                                            Да, но это не так для разработчика языка. Я вот планирую как-нибудь попробовать rust в реальном проекте, если получится, но создавать свой язык не планирую точно. А я даже не уверен, что для Mozilla Foundation rust окупился, хотя у них — совсем другие масштабы…
                                                                        0
                                                                        про расширения ссылку бы
                                                                    0
                                                                    Некорректно сравнивать «одинаковые» ситуации с разными языками, поскольку различия у ситуаций всегда не только в языке
                                                                –1
                                                                Быстрее? Тормозит безбожно. И теперь я понял почему.
                                                              +1
                                                              Миллиарды строк легаси будут использовать new
                                                                –1

                                                                Вы невнимательно прочли. Комитет должен рекомендовать начинать писать новые проекты на Раст, а не на С++. Тогда всем будет счастье.

                                                                  0
                                                                  Я рассуждал так — если комитет объявляет о закрытии c++ для всех новых проектов, следовательно, c++ тоже подлежит закрытию, как проект. Из чего следует, что легаси остается осиротевшим, из чего следует необходимость переноса легаси на раст.
                                                                    0

                                                                    Ну что вы. Легаси — важное наследие, которое необходимо поддерживать.


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


                                                                    Поэтому одним из возможных важных этапов С++ было бы… делегирование своего продолжения в Rust, где уже все это пофикшено. Надеюсь, вы поняли мою мысль)

                                                                +18
                                                                фанаты раста в тредах про с++ как веганы на барбекю пикнике. Орут громче всех, а кто вас звал то?
                                                                  +2

                                                                  Я умею и в С++, и в Раст. Так что имею право.

                                                                    +2
                                                                    я же, например, не ору в тредах про js что python лучше.
                                                                  0
                                                                  Я не понимаю, почему комитет не задеприкейтит создание новых проектов на этом языке в пользу Раста

                                                                  Может быть потому, что ребята, которые пилят раст, сами решают, что станет стандартом в их языке, и делегировать это право комитету в их планы не входит?
                                                                  Или вы предлагаете тупо списать? :)

                                                                    0

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

                                                                      0
                                                                      Питонисты пробовали на своем примере. Сколько их там сейчас, кроме общепризнанного CPython? Jython, IronPython, PyPy, RPython, это первое что гугл выдал. А большая часть народа все равно живет на CPython.
                                                                  +19
                                                                  Прочитал заголовок, обрадовался, перечитал заголовок, посмотрел на дату, взгрустнул. Согласен с подходом Rust, когда указатели, конечно, не deprecated, но почти на все случаи жизни существуют ссылки и другие безопасные аналоги. Проблема недостатка безопасных аналогов как раз находится в процессе решения: string_view, span, observer_ptr.
                                                                    +1
                                                                    Оригинал статьи-то вроде как от 26 марта…
                                                                      +1

                                                                      string_view и span не являются безопасными. Объект, на который они ссылаются, может быть удалён или перемещён, а вы и не заметите. Пример:


                                                                      std::string_view sv = function_returning_string();

                                                                      Тут string_view будет dangling, потому что ссылается на временную строку, которая сразу будет уничтожена.

                                                                      +38
                                                                      Забавно, 5 статей (no-new-new, cpp-will-no-longer-have-pointers, no-pointers, raw-pointers-are-gone, deprecating-pointers) ссылающихся друг на друга по кругу — довольно хорошо ребята подготовились. Если бы еще c isocpp.org договорились, вобще бы умора была.
                                                                        +7

                                                                        Да Вы, батенька, настоящий детектив!

                                                                          0
                                                                          Да, я сегодня утром тоже заметил) в тг-чат крестовый кидали оригинал английский )
                                                                            0
                                                                            западня для кроулеров?
                                                                            +5

                                                                            А если серьёзно, то C++ не хватает для умных указателей нормального синтаксиса.
                                                                            Зачем писать std::unique_ptr<T>, когда можно писать T^?
                                                                            Зачем писать std::make_unique<T>(...), когда можно писать new T^(...)?

                                                                              +2
                                                                              А как вы будете обозначать shared_ptr? А weak_ptr? И еще какой-нибудь com_ptr, нестандартный но иногда очень нужный? Спецсимволов же не хватит…
                                                                                +1
                                                                                Достаточно краткой записи только для unique_ptr и shared_ptr. Редкоиспользуемые случаи же спецсимволами покрывать не нужно. Мне C++ очень нравится, но многословность несколько выбешивает.
                                                                                  +2
                                                                                  Сделайте макрос, если очень хочется и не будет многословности.
                                                                                  А лезть с синтаксическим сахаром в стандарт не нужно. Особенно с аргументацией «мне нравится unique_ptr, для его давайте схара, а остальные не надо, я ими не пользуюсь»
                                                                                    +3
                                                                                    Говориш не надо тебе сахара? Может и range based for тебе не надо?
                                                                                    Только из за добавления сахара с++ стал юзабельным. С отвращением вспоминаю всё что было до с++03\с++11.
                                                                                    Необходимость синтаксиса для «умных» указателей это следствие наличия в языке:
                                                                                    а) Стандартного аллокатора, который по умолчанию используется для всего,
                                                                                    б) Деструкторов — суть и соль языка,
                                                                                    в) Собственно, необходимости работать с указателями.

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

                                                                                      0
                                                                                      Который из умных указателей он должен возвращать? Самый нафаршированный, и потому медленный shred_ptr, или чего попроще?
                                                                                        0
                                                                                        new — не такое часто используемое слово, чтобы экономия 10 знаков в сравнении с make_shared/make_unique была существенной. range based for нужен больше потому, что с ним ошибок меньше.
                                                                                          0
                                                                                          Возможно вы меня не так поняли. У нас есть язык, и программирование на нём построено вокруг различных идиом в основе которых лежит использование деструкторов. В этом языке есть алакатор по умолчанию и есть оператор создания объекта, являющийся частью языка а не стандартной библиотеки.
                                                                                          new — часть языка, и для того чтобы язык выглядел более самодостаточным, было бы логичным что new возвращяет безопасный указатель, с однозначным намёком что этот указатель надо будет освободить, после использования.
                                                                                    +2
                                                                                    Для себя писал макросы чтобы можно было так писать
                                                                                    struct MKSHARED
                                                                                    {
                                                                                    	template<class T>
                                                                                    	std::shared_ptr<T> operator*(T* ptr)
                                                                                    	{
                                                                                    		return std::shared_ptr<T>(ptr);
                                                                                    	}
                                                                                    } MK_SHARED;
                                                                                    #define shared MK_SHARED*
                                                                                    
                                                                                    auto p = shared new SomeClass();
                                                                                    auto v = unique new SomeClass();
                                                                                    
                                                                                    +1
                                                                                    Внезапно нечто подобное уже есть в Visual Studio.
                                                                                      0

                                                                                      Да, это штука из Managed C++, а не из стандартного C++.

                                                                                      +1
                                                                                      Если тащить все в синтаксис языка вместо реализации в библиотеках, через некоторое время язык превратится в свалку из странных синтаксических конструкций, но хватать их все равно не будет. А запомнить, какая из комбинаций знаков препинания создает shared_ptr, какая weak, а какая — вообще std::thread будет невозможно никому
                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                        +1
                                                                                        Может, перейдете на APL или J, на худой конец?
                                                                                        +4
                                                                                        Сломается обратная совместимость, ибо new T^(...) — валидная конструкция с вполне определённым смыслом:
                                                                                        struct T{};
                                                                                        
                                                                                        T *operator^(T *lhs, T)
                                                                                        {
                                                                                        	return lhs;
                                                                                        }
                                                                                        
                                                                                        int main()
                                                                                        {
                                                                                        	T x;
                                                                                        	T *ptr = new T^(x);
                                                                                        }
                                                                                        


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

                                                                                          Это следствие отсутствия ключевого слова "function".

                                                                                            0
                                                                                            В шаблонах даже без функций есть неоднозначности между объявлениями и выражениями — как, например, в случае a::b * c или a::b<c> d, где a — параметр шаблона.
                                                                                        +11
                                                                                        Первое апреля…
                                                                                          +22
                                                                                          Еще к 23 году уберут постфиксную форму ++ ввиду ее неэффективности, а сам стандарт переименуют ++c23
                                                                                            +5
                                                                                            Как хорошо, что это шутка. У меня даже сердце остановилось.
                                                                                              +1
                                                                                              Оригинал статьи от 26 марта… www.modernescpp.com/index.php/no-new-new
                                                                                                +3
                                                                                                И эта статья ссылается на статью от 1го апреля как на источник.
                                                                                                0
                                                                                                Столько копий было сломано. А ведь достаточно было просто обратить внимание на метки:
                                                                                                Метки:
                                                                                                c++
                                                                                                c++20
                                                                                                1 апреля
                                                                                                0
                                                                                                И вас также с праздником :-)
                                                                                                  0
                                                                                                  Сначала челюсть немного отвисла; потом вспомнил, какой сегодня день)
                                                                                                    +2

                                                                                                    В каждой шутке есть доля шутки. Указатели позволяют слишком много. Ссылки обрезаны по самое небалуйся. reference_wrapper имеет почти нужную семантику, но, как ни смешно, слишком длинное имя. А optional из стандарта не имеет sentinel value оптимизации, из-за чего проигрывает голым указателям и по размеру, и по совместимости. К тому же слишком "легко" превращается в голое значение. В общем не хватает чего-то вроде optional<ref<T>>, имеющего почти нулевой оверхед по сравнению с указателем (за вычетом ассёртов в отладочном режиме).

                                                                                                      +3
                                                                                                      Возьмите c++ core guidelines и пишите в строгом соответствии с ними — никто же не мешает.
                                                                                                        0

                                                                                                        Если вы про owned/notnull — они дают какую-то семантику только в паре со статическим чекером, который их понимает. Последний раз такой чекер был только в Visual Studio. Т.е. его работоспособность даже в VS Build Tools под вопросом. В целом же, как я вижу, С++ всё больше требуется отдельный независимый от компилятора DSL для описания статических проверок :)

                                                                                                          0
                                                                                                          Чего… Визуальная Студия все свои правила из библиотеки берёт. Но ассобенно сомневающиеся могут и саму Студию с командной строки запустить. В серьёзном проэкте всегда нужен свой статический анализ кода. У меня на проэкте гуру пишет базы для проэкта 25-й год. Она меня целует, за статический анализ. Когда глава фирмы прибегает и ждет, чтобы выдали новую процедуру такое пишут, что никаким опытом и знаниями волнение не защитить.
                                                                                                      +1
                                                                                                      C++ core guidelines: Resources management:
                                                                                                        +4

                                                                                                        Это всё хорошо, но не описывает borrowed pointers и not-null pointers независимо от компилятора.

                                                                                                          0

                                                                                                          Насчёт 11: предпочитаю всегда писать std::unique_ptr<T>(new T(...)), чем std::make_unique<T>(...). Причина простая: в первом случае работают подсказки IDE, во втором случае — нет.

                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                            0
                                                                                                            Я поверил статье пока не дошел до тэгов… :)
                                                                                                            AFAIK, тэги собирались удалять с Хабра (честно признаюсь: не ищу статьи по тэгам), но в данном случае тэги сыграли свою роль. Поэтому считаю что тэги на Хабре нужно оставить.
                                                                                                            P.S. С прошедшими Днём Архивов и Днём Дураков!
                                                                                                              –9
                                                                                                              Смех — смехом, но «развитие» С++ именно, что похоже на чью-то дебильную, 1-апрельскую шутку! Или же на известный квартет, меняющийся местами. Что бы в С++ ни ввели, безбожно уродливый синтаксис, вкупе с «совместимостью неуклюжей ООП модели», оставляет язык без шансов. Ну попрыгают ещё старпёры со своими «умными указателями», ещё пару сотен «списиалистов» выпустят ВУЗы, но язык так и останется «трупом страуса». Он просто ТУПИК.
                                                                                                              Комитет, вместо проедания денег, лучше бы взялся за D — вот уж кому не помешали бы деньги и дополнительные ресурсы! Ди решил множество проблем Сипипей, но комитет старых пердунов продолжает насиловать стюардессу, год от года становясь всё более смешным.
                                                                                                                +2
                                                                                                                Выше уже были комментарии про растовцев:
                                                                                                                фанаты раста в тредах про с++ как веганы на барбекю пикнике. Орут громче всех, а кто вас звал то?

                                                                                                                В каждый пост про С++ приходят фанаты раста и начинают объяснять как «правильно» надо программировать.

                                                                                                                так вот, к фанатам D, как ни странно, то же самое полностью подходит :)
                                                                                                                  0
                                                                                                                  Смех — смехом, а эта «первоапрельская» фича в D есть :P
                                                                                                                  0
                                                                                                                  Соберите свой комитет по D, добейтесь авторитета в индустрии, народ к вам потянется, компиляторы напишет под ваш стандарт, компании начнут свой код на ваш D переносить. <<Тогда и поговорим>>
                                                                                                                    –2
                                                                                                                    Когда «компании начнут переносить код», зачем мне тогда говорить с неудачниками на этом форуме?? :)))))
                                                                                                                  +1
                                                                                                                  Пошутили, блин. Давно такого дикого срача не видел в комментариях. Как же все напряглись-то.
                                                                                                                    0
                                                                                                                    Кроме того, чтобы скомпилировать старую программу с помощью новых версий компилятора Microsoft без ошибок к сигнатуре каждой функции будет необходимо добавлять спецификатор "__unsafe_please_do_not_remove"
                                                                                                                      0
                                                                                                                      Интересно, 55 плюсjв у статьи — это от тех, кто понял шутку, или от тех, кто не понял? :)
                                                                                                                        0
                                                                                                                        Через год ждать анонса GC? :)
                                                                                                                          0
                                                                                                                          Опциональная поддержка GC (как я понимаю, без возможности вызова деструкторов) появилась ещё в C++11 (safely-derived pointers, std::declare_reachable и т. п.).
                                                                                                                            0
                                                                                                                            0
                                                                                                                            никто никуда переходить не будет :) если с++ станет удобнее, он только закрепит свои позиции популярного языка, тем более, что язык развивается — есть и перспектива, и проверенная годами практика.
                                                                                                                              0
                                                                                                                              Это очень жестоко.
                                                                                                                                0
                                                                                                                                А зачем убирать указатели? Их же можно просто не использовать.
                                                                                                                                  +2

                                                                                                                                  Вот вышла краткая заметка о первоапрельском розыгрыше: Правда о "Указатели удаляют из C++".


                                                                                                                                  Пять блогеров с разных уголков Земли договорились разыграть читателей в День дурака новостями об избавлении от указателей. Отклик на пять статей был гигантским, и растянулся от "давно пора!" до "это не может быть правдой!".

                                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                      –4
                                                                                                                                      Не верю. Что старый добрый C++ откажется от своей, возможно, главной особенности: производительности. Все эти shared_ptr и unique_ptr («эти» я пишу потому что я не любитель GC и сижу на C) просто в принципе не подходят для гейм-девелопмента. Никто не хочет 1 FPS в Counter-Strike: Global Offensive. Никто не хочет, чтобы огромную кодбазу на C++ переводили на C. Именно поэтому это просто утка…
                                                                                                                                        +4
                                                                                                                                        Все эти shared_ptr и unique_ptr просто в принципе не подходят для гейм-девелопмента.

                                                                                                                                        unique_ptr ничуть не медленнее пары new/delete. Оверхед от shared_ptr в подавляющем большинстве случаев микроскопический в рамках приложения. Тем более что вы как сишник должны знать как часто в управлении временем жизни объектов на си используется тот же самый подсчет ссылок, что и внутри shared_ptr
                                                                                                                                          +1

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

                                                                                                                                          0
                                                                                                                                          При чем тут вообще GC? shared_ptr и unique_ptr никакого отношения к сборщику мусора не имеют.
                                                                                                                                            +1
                                                                                                                                            Refcounting — вполне себе можно считать видом сборки мусора кмк.

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

                                                                                                                                        Самое читаемое