Современный C++: что это и как он появился?


В течение последнего десятилетия с приходом стандарта C++11, а перед этим — предваряющих его спецификации TR1 и библиотеки Boost, — в сообществе C++-разработчиков наблюдался массовый переход на новый стиль программирования, так называемый современный C++. Этот переход подразумевал введение в оборот таких приемов как ключевое слово auto, замыкания (лямбда-выражения), вариативные шаблоны и многое другое. C++ оказался благодатной почвой для экспериментов, и на свет появилось несколько библиотек, написанных в новом стиле. Те, кто смог разобраться в новых идиомах вроде SFINAE, диспетчеризации тегов, CRTP, генератора типов, безопасного bool и т.д., или хотя бы научился их воспроизводить, были награждены званием гуру.

С появлением в начале 1970 -х гг. интуиционистской теории типов Мартин-Лёфа, которая представляет собой результат скрещивания чистой математики и информатики, начался период активных исследований в области языков нового типа, таких как Agda и Epigram. Так был заложен фундамент парадигмы функционального программирования. Все эти теории сейчас преподаются в вузах и провозглашаются в качестве «прорыва», а в их развитие и продвижение вкладываются огромные средства. Появилось даже целое сообщество ораторов, зарабатывающих на жизнь пропагандой этого «прорыва» среди представителей деловой Америки. Поэтому неудивительно, что на текущие решения Комитета по стандартизации C++ активно влияют новые члены — вчерашние студенты, чье мнение было сформировано под воздействием этого окружения.

Переориентация с производительности на функциональность


Со временем C++ превратился из «быстрого» языка в «функциональный», и о производительности забыли. Сейчас уже ни для кого не секрет, что некоторые компоненты C++, например, библиотека iostream и строки, в силу своей природы не могут работать быстро; кроме того, отсутствуют некоторые основные возможности вроде управления передачей данных по сети и совсем уж базовые функции, например, простейшая процедура разбиения строк. Если спросить любого члена Комитета, почему эти недостатки так и не устранили за прошедшие почти двадцать лет, ответ неизменно будет один и тот же: потому что никто не хотел возиться с подготовкой соответствующего доклада или предложения.

Комитет рассчитывает использовать исследовательскую группу SG14 — подразделение Рабочей Группы ISO 21 (WG21), посвященное разработке игр и высокочастотному трейдингу (HFT) — в качестве платформы для обсуждения дальнейших улучшений языка между специалистами из индустрии ПО с низкими задержками. Однако, судя по уже состоявшимся обсуждениям в дискуссионных группах и Стандарту Майкла Уонга (его содержание такое же забавное, как и название), никто не горит желанием проводить радикальные реформы, которые так необходимы C++, чтобы успешно конкурировать в этой области с «C++ с классами».

А почему это, собственно, проблема?


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

Потеря производительности


Первый камень преткновения, как уже говорилось, — это потенциальная потеря производительности по причине более сложного устройства структур промежуточного представления кода и проходов компилятора. С этой точки зрения Fortran намного лучше, поскольку он проще и компиляторы могут гораздо эффективнее оптимизировать его по сравнению с аналогичным кодом на C/C++. Мой собственный опыт работы в сфере HFT и разработке игр в течение многих десятилетий, а также данные авторитетных рецензируемых изданий, да и вообще наблюдения любого, кто немного разбирается в оптимизациях компилятора, показывают, что распространенное убеждение, будто обычные и вариативные шаблоны позволяют получать на выходе намного более быстрый ассемблерный код благодаря автоматическому «растворению» C++ кода на этапе компиляции, не подтверждается на практике. Это не более чем заблуждение, при этом весьма устойчивое. Фактически имеет место обратное: небольшие фрагменты кода гораздо лучше компилируются, отлаживаются и оптимизируются, когда работаешь со сгенерированным ассемблерным кодом, а не с шаблонами.

Время компиляции


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

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

Сопровождаемость


Третье, и последнее, препятствие связано со сложностью кода. Как однажды сказал Эдсгер Дейкстра,

Простота — залог надежности.

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

Если внимательно прочитать, пожалуй, самую известную статью Дейкстры, «О вреде оператора goto», нетрудно заметить, что самые главные ее положения распространяются и на шаблоны (обычные и вариативные): дело не в том, что плох сам механизм, а в том, что изначально присущая ему структура неизбежно порождает сложный код, что в конечном счете нивелирует самое главное достоинство качественного кода — его понятность.

При создании торговых систем, когда по сети пересылается до 100 000 заявок в секунду, а торговые стратегии разрабатываются и реализуются каждые два дня, простота кода не просто желательна — она необходима. Отсюда мое «правило одной минуты» при разработке подобных систем:

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

Истинная причина


Однако истинная причина, по которой я почти перестал иметь дело с современным C++, несмотря на то что весьма преуспел в нем, заключается в том, что в IT-индустрии появляется все больше разработок, которым действительно стоит уделять внимание.

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

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

Современный разработчик, если он действительно хочет идти в ногу со временем, вынужден обращаться к новым языкам — Verilog и VHDL; он должен уметь проектировать собственные процессоры и виртуальные модели материнских плат, иначе он не совладает с лавиной технологических достижений ближайших лет. И дело не в том, что ППВМ (Программируемая пользователем вентильная матрица, Field-Programmable Gate Array, FPGA) отличаются сверхвысокими скоростями — это совсем не так. На самом деле они на порядок медленнее, чем топовые процессоры.

Просто сейчас появляется все больше всевозможных реконфигурируемых вычислительных систем. Например, Intel поставляет процессоры Xeon со встроенными ППВМ, а «Интернет вещей» (Internet of Things, IoT) в ближайшие пять лет превратится в рынок с оборотом в миллиарды долларов, и двигателем этого процесса в значительной степени выступают маленькие десятидолларовые ППВМ, для программирования которых придется нанимать целую армию квалифицированных технологов. И поверьте мне, программировать на уровне RTL (register transfer level, уровень регистровых передач ) в сотни раз сложнее, чем писать код на C++. И если изучение C++ дается нелегко, представьте, каково осваивать ППВМ-программирование на профессиональном уровне (документация к одному только инструменту Transceiver Toolkit от Altera занимает 700 страниц, к среде разработки Quartus — еще 1000, и это не говоря уже о продукции Xilinx).

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

Заключение


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

Примечание переводчика


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

Ах, да, чуть не забыл. Используйте статические анализаторы кода, чтобы уменьшить хотя бы количество глупых ошибок — и без них головной боли с C++ хватает.
Поделиться с друзьями
-->

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


  1. spot62
    25.05.2016 15:36
    +10

    VHDL, Verilog — это не языки программирования, а языки описания аппаратуры


    1. Atakua
      25.05.2016 17:45
      +7

      Может быть и непривычные, но это языки программирования. Как и, например, Postscript, TeX. Ну или эзотерические языки вроде BF, лямбда-исчисление Чёрча или ДМТ.


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


      1. Aquarius-Michael
        25.05.2016 20:38
        +3

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


        1. ZyXI
          25.05.2016 21:16
          +1

          Из того, что процессор исполняет свои инструкции последовательно (что уже давно не совсем так), совершенно не следует, что запись вашей программы на каком?нибудь Prolog или Haskell выполняется последовательно, как она написана. Компилятор даже в ходе оптимизаций может что?то переставить, а уж в указанных языках? порядок вычислений далёк от порядка их записи. Языком программирования называют языки, на которых вы можете описать какой?то алгоритм так, чтобы его мог выполнить компьютер, и HDL этому соответствуют. Если вы напишете программу на другом языке, то чтобы она отработала вам придётся её запустить (возможно, перед этим скомпилировав), программа на HDL тоже требует определённых условий для выполнения. От того, что эти условия сильно различаются, HDL не перестаёт быть языком программирования, а с ПЛИСов не исчезает программа — ни программа на C, ни на VHDL не заработает в сферическом вакууме без чьей?то команды.


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


          1. Aquarius-Michael
            25.05.2016 21:41
            +2

            Но на ПЛИСе может и не быть алгоритма вообще. ПЛИСы называют программируемыми потому, что можно задавать их параметры и поведение с помощью сторонней программы. Вот устройства PROM, EEPROM и ему подобные называют программируемыми, потому что этими устройствами можно управлять с помощью внешней программы. Как и здесь с ПЛИСом. Да и вообще для ПЛИС существует понятие как синтез, а не компиляция. Компиляцию можно увидеть только в симуляторе как ModelSim. А в остальном пишется именно синтез исходного текста для ПЛИСа. Процессор пусть и с внеочередным выполнением кода всегда будет выполнять последовательно и в соответствии с кодом программы последовательно, то есть за каждый такт или цикл.


            1. Mirn
              25.05.2016 22:56
              +4

              А в остальном пишется именно синтез исходного текста для ПЛИСа.
              немножко неправильно, я бы сформулировал так: «исходный текст для ПЛИС описывает связи блоков и настройки блоков в кристалле.»
              т.е. мы просто описываем эл схему, её связи и её настройки.
              Всё, ничего другого нет.

              Ни последовательного выполнения, эти связи всего лишь провода и значения R\C\L внутри кристалла.
              Нет и битов — в плис минимум 3 состояния, в реальных средах их куда больше, а по факту это всё аналоговые величины.
              Нет даже времени: есть суперпозиция расстояния/времени/неопределённости/шума, то-что топологически разнесено дальше друг от друга работает медленее и/или менее детерминированно. Всё потому что триггеры срабатывают в определённом временном окне, в определённом интервале напряжений и их вероятность срабатывания далеко не чёткий порог под 90 градусов.

              Для плис никто не требует наличия даже клоков и тактовой величины — можно без неё обойтись.
              Наличия лог уровней и бит тоже, можно работать в аналоговом режиме — просто подключить кварец на два входа в плис и внутри реализовать полу-аналоговый генератор тактовой, а если заморочится то получить даже синус на выходе, а если ещё позаморочиться то и с возможностью подстройки. ЦАП и АЦП на плис так же спокойно делают, на хабре даже видел кто то запилил аналоговое радио.
              А я например один раз отказался от принципа хранения данных в триггерах и хранил их в логических блоках (LCELL) делая линии задержки и снимал с них скрины — видя двоичную осциллограмму на 15+ гигасемплах тем самым обходя предел работы триггеров в примерно 500-1000Мгц.

              А настройки портов ввода вывода, их силы, параметров и логических уровней это целый отдельных и порой сложный язык где 99% это схемотехника и физика.
              Аналогично с настройками допустимых окон времени прохождения сигналов, чего стоит тот факт что он стремится описать всё ко всем.
              Так же есть системы и описания моделирования потребления/шума/разводки (но я о них редко слышал).


              1. Aquarius-Michael
                25.05.2016 23:03

                Да, согласен. Просто я имел ввиду, что программы Altera и Xilinx, с которыми я постоянно работаю, пишут в логах как синтез. И только для симуляторов типа ModelSim пишется в логах как компиляция.


      1. Lol4t0
        25.05.2016 23:40

        Ну тогда HTML -тоже язык программирования


        1. Atakua
          01.06.2016 15:35

          Смотря какая версия HTML.


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


          1. saboteur_kiev
            01.06.2016 22:05
            +1

            Чорт, кстати да, с html5 контент менеджерам нельзя будет теперь называть себя HTML-программистами


      1. spot62
        29.05.2016 00:23

        http://dic.academic.ru/dic.nsf/ruwiki/1421


      1. deko
        01.06.2016 14:19
        -1

        Всё же неточность: PostScript — язык описания страниц, Tex — язык низкоуровневой разметки в системе компьютерной вёрстки. Язык программирования — всегда инструмент написания алгоритмов. В системах пожарной сигнализации также можно задать алгоритм срабатывания сирены, дозвона, и это называют в быту программированием, хотя фактически является конфигурированием, даже несмотря на то, что в результате получается простейший алгоритм.
        Я не говорю, что конфигурирование проще программирования, просто это принципиально разные вещи.


        1. Atakua
          01.06.2016 15:29

          Два контрпримера:


          pshttpd — веб-сервер, написанный на Postscript 1) http://www.pugo.org/project/pshttpd/ 2) https://people.debian.org/~godisch/pshttpd/


          basix — интерпретатор языка Basic, написанный на TeX: https://www.tug.org/TUGboat/tb11-3/tb29greene.pdf


          1. deko
            01.06.2016 15:41
            -1

            Примеры, и правда, интересные, но согласитесь, таким подходом много толкового не напишешь. Да и первый пример, фактически, CGI-скрипт. Для полноценного сервера нужно ещё системный API вызвать, сокет открыть, а pshttpd всё же придётся положить под inetd.


            1. Atakua
              01.06.2016 15:55

              Ну конечно же. Статья провокационная, поэтому и комментарии к ней такие же.


              Да и первый пример, фактически, CGI-скрипт.

              Это мог бы быть CGI-скрипт на Perl, на Bash, ну или программа на Си.
              Да и для "обычных" двоичных программ точно так же обязан иметься загрузчик, который разберёт их структуру, поместит секции в память и передаст управление на точку входа. Но это не делает машинный код "языком разметки".


        1. klirichek
          02.06.2016 16:02
          +2

          PostScript — вполне нормальный язык программирования. Нагуглите файл ThinkingInPostScript.pdf, подывитесь!


    1. Gorthauer87
      25.05.2016 18:36
      +3

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


  1. apro
    25.05.2016 15:37
    +28

    вынужден обращаться к новым языкам — Verilog и VHDL


    Может стоит написать новым для себя, а то C++, Verilog и VHDL появились примерно в одно
    время ~ 1980-1985


  1. orcy
    25.05.2016 15:52
    +6

    Допустим написал ты игру на Verilog, и как же ты будешь ее распространять? Рассылать по почте коробки за 500 баксов?

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



  1. gbg
    25.05.2016 15:55
    +6

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


    1. darkAlert
      25.05.2016 16:56

      Можете пояснить? Честно, хочу понять.


      1. gbg
        25.05.2016 17:17

        Функциональная программа — это почти готовый потоковый граф вычисления выходных данных по входным. В таком графе легко найти параллельно идущие ребра — вот вам и распараллеливание.

        Исходными данными для САПР, генерирующей настройку ПЛИС, также является потоковый граф. Так что функциональные языки, с теоретической точки зрения, обладают огромным потенциалом.


        1. Gorthauer87
          25.05.2016 18:38

          То есть возможно написать рабочий транслятор лиспа или хаскеля в VHDL и он будет давать хороший результат?


          1. gbg
            25.05.2016 18:47

            Теория утверждает, что да. Более того, аппаратные LIsp-машины когда-то существовали (в количестве 7000 экземпляров)

            Разумеется, результат будет сильно зависеть от того, что пойдет на вход этого транслятора.


          1. Leeb
            26.05.2016 01:00
            +1

            Работы в этом направлении ведутся уже заметное количество времени. Например


      1. lorc
        25.05.2016 17:29
        +6

        Идея в том, что в функциональном программировании используются «чистые» с точки зрения математики функции. Они не имеют побочных эффектов, а значит — в принципе не могут иметь общего состояния — основной проблемы при распараллеливании.
        Например, нам надо совершить какое-то действие над каждым элементом массива из N элементов. Самая обычная конструкция на любом императивном языке: foreach elem in array: process(elem). Элементы будут обрабатываться один за другим, потому что мы не знаем, что делает process(). Возможно ей важен порядок вызовов.
        В случае любого функционального языка мы точно знаем что process() — чистая функция, и элементы ей можно скармливать в любом порядке или вообще паралельно. Если у нас вдруг совершенно случайно есть N процессоров, то интепретатор может отдать каждому процессору по одному элементу и при этом он будет уверен что результат выполнения будет точно таким же, как если бы он работал на одном процессоре и обрабатывал элементы один за другим.

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


        1. kemiisto
          25.05.2016 22:30
          +4

          «Чистые» функции уже много лет как есть во многих императивных языках программирования, например, в том же Fortran. И основная проблема «распараллеливания» заключается в том, что большое число алгоритмов либо вообще нельзя «распараллелить», либо можно, но крайне не эффективно. А наличие глобального состояния уже давно научились избегать (там, где надо) и в императивных языках.


        1. Lol4t0
          25.05.2016 23:44
          +2

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


          1. gbg
            26.05.2016 06:56

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


            1. Lol4t0
              26.05.2016 10:00

              А вы можете привести пример, потому что я не понимаю, о чем вы говорите. Какую таблицу раскрутить в каких пределах и что получится?


              Рекурсивная функция вычисления факториала и так чистая, кстати, как можно получить еще более чистую.


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


              1. develop7
                26.05.2016 10:04

                речь, вероятно, о tail call elimination


                1. Lol4t0
                  26.05.2016 10:11

                  А что за пределы? И что захардкодить?


              1. gbg
                26.05.2016 11:45
                +1

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

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

                Под «разумными пределами» здесь я вижу экономически целесообразный размер такой предвычисленной таблицы.


      1. Chupans
        25.05.2016 22:30
        +3

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


        1. konsoletyper
          26.05.2016 11:48
          +3

          Вот только когда состояние есть (объективно, присутствует в требованиях), то поступают вот как: берут функцию, которая принимает предыдущее состояние и трансформирует его в следующее состояние. Haskell умеет это дело аккуратненько прятать, заворачивая в монады и засахаривая do-синтаксисом. Проблема в том, что получившееся дерево комбинатором можно редуцировать только в определённом порядке (только «хребет» графа). Распараллелить можно только если относительно каких-то подграфов можно доказать, что их можно редуцировать параллельно это никак не затронет семантики редукции. Так вот отказывается, что и в теории и на практике это сделать ничуть не проще, чем для привычного императивного CFG доказать, что его куски можно исполнять параллельно.

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


      1. knagaev
        26.05.2016 12:22
        +2

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


        1. konsoletyper
          26.05.2016 13:41

          Ещё как важен! Взять ту же функцию reduce (fold, aggregate). Если переданная ей ФВП не обладает «хорошими» свойствами типа ассоциативности или коммутативности, порядок вычисления возможен только один. А поди ещё докажи эти свойства в компиляторе: чаще всего это в общем случае неразрешимая задача. А для частных случаев оптимизации прекрасно работают и в императивных языках.

          Кстати, вот reduce — это частный случай. А как в общем случае заставить компилятор понять, что если мы в функцию передаём что-то ассоциативное, то её можно по-другому посчитать?


          1. knagaev
            26.05.2016 15:28

            Подождите… Reduce (fold) получает на вход лист, а лист всегда имеет порядок.
            Или я совсем не понял последний вопрос — что такое что-то ассоциативное?


            1. konsoletyper
              26.05.2016 15:34
              +1

              Классический reduce получает на вход три параметра: исходное значение, бинарную функцию и список. Если бинарная функция является ассоциативной, то reduce можно распараллелить, иначе — нельзя. Проблема в том, чтобы автоматически доказать ассоциативность переданной функции. Вторая проблема в том, что есть неассоциативные функции, к которым хочется применить reduce (и это никак не оптимизируешь).

              Далее, указанная оптимизация касается только специально написанной функции fold, про которую компилятор заранее знает и заранее может её оптимизировать таким путём. А как быть с общим случаем, когда компилятор ничего не знает про природу fold? Как компилятор, посмотрев на реализацию fold, должен понять, что к ней можно применить такую оптимизацию?


              1. knagaev
                26.05.2016 15:51

                Ну всё, теперь понял.
                Я написал не о распараллеливании функции (внутри), а о распараллеливании выполнения нескольких функций.
                Если порядок выполнения не важен, то их можно выполнять параллельно (в контексте нашей беседы — map).
                Про распараллеливание кода foldа речи не было.
                Здесь действительно может быть возможность параллелизации, а может и не быть.


              1. Yuuri
                27.05.2016 00:44
                +1

                Тем не менее, невозможность автоматически всё вывести в общем случае не лишает нас некоторого дополнительного профита в частных. Возьмём условную par_mconcat :: Monoid m => [m] -> m:
                1. Ограничение на то, как должна делаться свёртка, явно указано в сигнатуре функции; и хоть злобному программисту по-прежнему ничто не мешает сделать кривую реализацию своего моноида, это всё-таки сильнее будет бросаться в глаза, чем если просто нечаянно передать неассоциативную функцию.
                2. В языках вроде Agda или Idris можно таки заставить программиста доказать ассоциативность и прочие свойства. В не-чистых языках это было бы невозможно в принципе. (да, я знаю, что для любой мало-мальски нетривиальной функции на порядки быстрее и проще будет обложить её юнит-тестами во всех немыслимых конфигурациях, чем выписывать формальное доказательство)
                3. Ещё можно поспекулировать на тему автоматических оптимизаций. Предположим, компилятор может использовать доказанные в (2) свойства в качестве rewrite rules, тогда он может, например, у того же fold'а развернуть несколько вложенных вызовов, перетасовать их и найти подтермы, которые можно вычислить независимо. Впрочем, не знаю, делается ли это где-нибудь.


  1. Vass
    25.05.2016 16:20
    +16

    Первый раз слышу идиому «C++ с классами», он и так с классами, может все-таки имелась ввиду более известная: «C с классами»?


    1. darkAlert
      25.05.2016 16:57
      -3

      Скорее имелось в виду использовать классические стандартные конструкции типа new/delete вместо всяких shared_ptr и прочих современных штук.


    1. Andrey2008
      25.05.2016 17:09
      +6

      Да, не так написал. Поправлю.


  1. levap
    25.05.2016 16:24
    +15

    Вот это сравнение! С++ и Verilog/VHDL :) Как тёплое с мягким сравнивать. Это два инструмента для совершенно разных целей…


  1. tangro
    25.05.2016 16:38
    +14

    Статья забавна тем, что призывает уходить с С++ не на банальные Java\C#\Javascript, а на что-то необычное. А так — очередные «похороны С++», таких по 5 штук каждую неделю происходит.


  1. izvolov
    25.05.2016 16:46
    +29

    Ещё один "не осиливший".
    Такой поток бреда, что даже непросто ответить по пунктам.


    • "О производительности забыли"


      Наверное, поэтому весь STL заоптимизирован по самые гланды, чтобы при каждом удобном случае вызвать наиболее эффективную операцию.
      Наверное, именно поэтому в C++11 ввели возможность переноса и пробрасывания.
      Наверное, именно поэтому думают о введении сопрограмм.


      и т.д.


    • "строки в силу своей природы не могут работать быстро"


      1. В современных реализациях стандартной библиотеки короткие строки хранятся прямо внутри указателя. То есть память не выделяется в куче, а скопировать такую строку — всё равно, что скопировать целое число.
      2. string_view.

      Да, и, кстати, в Бусте есть разбиение строки, которые автор по непонятной причине называет "базовой операцией".


    • "Шаблоны слишком сложны"


      Показательно, что автор говорит не только о вариативных шаблонах, но и об обыкновенных.


      SFINAE, диспетчеризация тегов, CRTP — новые идиомы? Да щас.


      1. Костыль под названием "SFINAE" стар, как сами шаблоны, при этом "новые страшные" концепты как раз-таки позволят от этого костыля избавиться.
      2. Диспетчеризация по тегам существует столько же, сколько STL.
      3. Что касается CRTP… При чём тут вообще CRTP?

    • "C++ изначально ориентирован на последовательный способ передачи данных"


      Жаль, что об этом не знают разработчики библиотеки Boost.Compute.



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


    1. qadmium
      25.05.2016 22:30
      +2

      >автор по непонятной причине называет «базовой операцией».

      а что это не так?


    1. Noiwex
      25.05.2016 22:30
      +2

      Очевидный вброс.


    1. OlegMax
      25.05.2016 23:08
      +9

      Зато теперь мы знаем, что автор статьи консультант и знает много модных баззвордов — IoT, HFT, FPGA, VHDL…
      Ну а то, что C++ настолько долго компилируется, что проще ПЛИС на коленке запрограммировать, мы и так догадывались.


      1. grossws
        26.05.2016 00:05
        +2

        Особенно учитывая как быстр бывает синтез под FPGA..


        1. R6MF49T2
          27.05.2016 09:46
          +2

          Особенно если сравнить минимальную конфигурацию компа под компиляцию(синтез). Например под последние альтеровские арии для компиляции необходимо 48 GB оперативы и 24 GB свободного места на диске. Для понимания, даже в случае максимальной конфигурации компьютера, который может приобрести обычный человек, время компиляции(синтеза) может измерятся сутками.


    1. Lol4t0
      25.05.2016 23:49
      +3

      Все верно.


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


      1. Antervis
        31.05.2016 17:41
        -1

        простота влечет за собой эффективность процесса разработки. Но ни в коем разе не эффективность программы на выходе )


    1. Cryvage
      26.05.2016 12:02
      +4

      Тоже в недоумении. Что автор хотел всем этим сказать? Сначала я подумал, что он говорит, что не нужно городить кучу абстракций и шаблонов, там где нужна максимальная производительность. Но в итоге у него получилось что-то вроде: «Не нужно использовать абстракции и шаблоны нигде, потому что кое-где нужна максимальная производительность». А потом он и вовсе ушел от темы. Началось с того, что не нужно использовать современный C++, а закончилось тем, что пора валить с плюсов, и вообще будущее за интернетом вещей и надо программировать микроконтроллеры. И вот тут я просто впал в ступор. Смешались в кучу люди, кони.
      По теме, я всегда считал, что основная парадигма C++ это мультипарадигменность. Хочешь, используй шаблоны, хочешь — классы. А можно и то и другое одновременно. Можно написать в процедурном стиле, можно вообще в C-стиле. То есть C++ это, как бы, не один язык, а сразу много языков. И его основная сила, на мой взгляд, в том, что нет необходимости сочетать несколько языков, чтобы использовать в программе несколько парадигм. Разные парадигмы и стили программирования можно сочетать между собой нативно. При этом, не нужно задумываться о том, как использовать код, написанный на одном языке из другого языка. Можно написать часть программы, требующую максимальной производительности, в C-стиле, с указателями, битовыми операциями, и прочими прелестями. А остальную часть написать в ООП стиле. И все это будет одна программа, написанная на одном языке. Добавление функциональных элементов вполне вписывается в эту концепцию. Мультипарадигменность от этого еще больше увеличивается. Так что у меня нет ощущения, что язык свернул не туда. Он уверенно следует своему пути.
      На этом пути, как и на любом другом, могут возникать сложности. Прежде всего, это делает сам язык сложным. Он сложен, как для людей, так и для компилятора. И люди так устроены, что им сложно переключаться с одного стиля мышления на другой. Сложно переключаться между разными парадигмами. Вот это и есть две основные проблемы: сложность самого языка, и непонимание, в каком случае какую парадигму использовать. В принципе это типичные проблемы любого универсального, многофункционального инструмента. Но это не делает инструмент плохим. Был бы он другим, проблемы просто были бы другими. Но они бы все равно были.


      1. vlad72
        26.05.2016 21:39

        Да, автор мог просто написать «мне надоел универсальный язык» и объяснить почему. Вот это было бы интересно.


    1. zed_0xff
      26.05.2016 14:09

      Наверное, поэтому весь STL заоптимизирован по самые гланды, чтобы при каждом удобном случае вызвать наиболее эффективную операцию.


      при этом существует ненулевое подмножество STL-операций, для которых не-STL операция будет еще более эффективной


      1. izvolov
        26.05.2016 14:33

        Например?


        1. agent1319
          26.05.2016 23:02
          -3

          Любые операции требующие реаллокации — та же конкатенация. Аллокатор сам по себе. Алгоритмы, которые в гцц/шланге просто циклы(допустит тот же реплейс на строке есть for вместо вменяемой лоулетенси реализации memchr()) — да куда не глянь везде засада.

          А уж если у тебя не glibc, нынче модная musl(или что там щас модно) — замедление всех string/mem-функций гарантированно, да и сами глибцешные имплементации хоть и лучшие, но не идеальные.

          Если попроще. Допустим, все string/mem-функции в том же глибц представляют из себя набор реализаций для разных случаев и рантайм диспатчер — который спокойно бы свёртывался компилятором если бы функции были инлайн. Далее благодаря всяким концептам можно было бы узнать выравненные-ли и как данные, приоритетные типы операций. str.find(«test») — оно мне в компилтайме посчитает префикс-функцию? Вернее тут она не нужна, но всё же. Сгенерирует оптимальную оптимальную реализацию для данного паттерна?

          Я уж не говорю о том, что всё это спокойно экспортируется и в рантайм + прикручивается жит.

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


          1. Antervis
            31.05.2016 17:37

            все STL контейнеры позволяют использовать свой аллокатор памяти. new/delete переопределяются глобально. Пользуясь constexpr можно реализовывать всякие compile-time префикс функции. Проблемы на ровном месте придумываете.


    1. agent1319
      26.05.2016 21:41
      -8

      Ещё один «не осиливший».
      Естественно не осилившие.
      Наверное, поэтому весь STL заоптимизирован по самые гланды, чтобы при каждом удобном случае вызвать наиболее эффективную операцию.
      Это не правда. Если мы говорим об имплементациях стл — основная оптимизация там — уход от обобщенных имплементаций. Это основной признак того, о чём забыли упомянуть в статье, но что является устойчивым мифом в среде пользователей шаблонных интерфейсов — обобщенные реализация не состоятельны.

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

      Я не заметил разоблачения этого мифа в статье, но он очень популярен среди пользователей генерик-интерфейсов — они верят в оптимальные генерик-имплементации. Основан он на вере в мистическую силу компилятора, т.е. по-факту компилятор должен предоставить нам все имплементации оптимальные для каждого конкретного типа. Что опять же противоречит убеждению в том, что обобщенная реализация состоятельна как оптимальная.

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

      Глибцешный маллок — это тонна оверхеда по памяти, это дыры и адское месиво в хипе, ибо инстанс один на тред. Т.е. все контейнеры спископодобные обречены. Залил туда 10килло чистых данных — решил получить лентенси л1д — stl подарит тебе нежданчик с летенси л2. А т.к. инстанс один, то между элементами будут дырки от других аллокаций и лучшем случае получишь нежданчик ввиде летенси stlb, а в худшем вылезешь за stlb.

      Далее — реализация того же «O(1)» хешмапа обладает адских оверхедом по памяти — там не 10, не 100, не 1000 крат оверхеда. Хотя пользователи stl редко видят больше килобайта чистых данных.

      Вектор может поставить раком целый тред(на штеуде поставит раком и соседние треды, ибо выжрет 70%трупута рамы) на полсекунды из-за реаллокации чисто из-за того, что не умеет в реаллок(да, да, в реальном мире реаллок не копирует память, даже если возвращает другой адрес).

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

      Наверное, именно поэтому в C++11 ввели возможность переноса и пробрасывания.
      Почему в С++ вообще существует разница между копирование объекта и полей? Правильно — причина в самом С++, а вернее в raii. Т.е. перемещение является кастылём для raii, но никак не какой-либо оптимизацией.

      Да и сам новый тип ссылок решает 2проблемы — отсутствие возможности передать r-value по не константной ссылки, а так же новая перегрузка операторов/конструкторов. Всё это нужно из-за всяких раишных понятий владения.

      В сишке передаётся копия полей, указатель — никаких проблем. Нераишный вектор передаётся спокойно копией полей безо всяких кастылей.

      А сама raii показала свою полную несостоятельность — привет никакущие строки в С++, а так же все попытки создать нераишные строки(привет string_view).

      Наверное, именно поэтому думают о введении сопрограмм.
      Это очередной кастыль для реализация ассинхронных интерфейсов в крестах, при этом адски тормазной.

      Он просто не имеет смысла, а тот кто его проталкивает — использует его для обёртки над сишными интерфейсами, т.е. для разделения одной функции на множество калбеков, хотя ничего не мешает их написать руками. Т.е. функции типа: f() {data = read(); write(data);} будут преобразованы к read((data d){write(d);}); А там уже есть aio, epoll и уже с ним. Если использовать классы — там нет никаких проблем с контекстом — он хранится в самом объекте.

      Но насколько я понял — такая техника у майкрософт не осилилась(да и она не возможна в С++) и они решили пойти путём стеков и контекстов, что есть адский оверхед.

      В современных реализациях стандартной библиотеки короткие строки хранятся прямо внутри указателя. То есть память не выделяется в куче, а скопировать такую строку — всё равно, что скопировать целое число.
      Чё? Это невозможно. Можно пруфцы?

      Показательно, что автор говорит не только о вариативных шаблонах, но и об обыкновенных.

      Обожаемая мною, как и автором, вера в шаблоны верующих. Выше я уже объяснил почему обобщенные имлементации несостоятельны.

      Если ещё один миф о шаблонах, как о рантайм вычислениях, рантайм аргументах и иже с ним. Это не имеет смысла для современных компеляторов без которых С++ не существует. Миф о «метапрограммировании» так же является мифом в связи со скудными возможностям шаблонов — допустим, ещё никто не смог написать рантайм-принтф. Нет понятия «рантайм-память». В связи с этим тонна кастылей, которые еле-еле работают и собираются тыщу лет.

      Осталось только «шаблонный аргумент» и «вычисления crc в рантайме», но как я уже сказал — это умеет делать любой компилятор. godbolt.org/g/15h2UV — поиграйся.

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

      Вместо того, чтобы ввести вменяемый интерфейс к f(...) {} и рефлекшн — выкатывают адские кастыли на шаблонах. f(… -> struct arglist {}) {for(arg: arglist) {} }.

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

      Современный С++ позволяет писать быстро. Всё остальное враньё.

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


      1. agent1319
        26.05.2016 22:04
        -4

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


        1. gbg
          26.05.2016 22:11

          За какие грехи мне пришлось читать длинную простыню программистского пиджина, переполненного острым негативом? Вы критикуете здесь не язык, а его реализацию. Так вот, немногие языки могут похвастаться тем, что практически всю стандартную библиотеку можно наглухо вырезать и заменить собственным гениальным произведением, которое будет работать идеально, нет, сверхидеально!


          1. agent1319
            27.05.2016 00:46
            -4

            Оратор рассуждал об реализации? Я критикую реализацию — в чём суть претензий?

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

            Если же вырезать стандартную библиотеку из крестов — останется си с классами. Здесь говорится именно о современном С++ суть которого именно в этой стандартной библиотеки. Вырезать её можно и из си.


      1. izvolov
        26.05.2016 22:23
        +5

        никакими оптимизациями и не пахнет, ибо они попросту невозможны

        Рекомендую ознакомиться с концепцией обобщённого программирования.


        Почему в С++ вообще существует разница между копирование объекта и полей? Правильно — причина в самом С++, а вернее в raii

        Не понял.


        raii показала свою полную несостоятельность

        Что?! Где?! Когда?!


        Чё? Это невозможно. Можно пруфцы?

        Исходники стандартной библиотеки, которые поствляются с гэцэцэ и шлангом, открыты для чтения круглосуточно.
        Милости просим.


        1. agent1319
          27.05.2016 00:58
          -5

          Зря. Понеслась.

          Рекомендую ознакомиться с концепцией обобщённого программирования.

          Ответ на:
          Во всём остальном, что не является интерфейсом в glibc — никакими оптимизациями и не пахнет, ибо они попросту невозможны.


          Т.к. никаких опровержений моих слов не последовало — я вынужден констатировать слив.

          Не понял.

          Зачем вообще нужен нестандартный конструктор копирования для того же вектора(любого контейнера)? Правильно — для раии.

          Что?! Где?! Когда?!

          В строках. Раиишная строка не может в си-строку, не может в подстроку. string_view — пример вменяемой строки, которую не смогли сделать раиишной и не вводили 20лет только из-за раии.

          Это так же отвечает на все твои вопросы связанные с мув-семантикой. Почему у string_view её нет? Правильно — она нахрен не нужна, ибо не раии.

          Исходники стандартной библиотеки, которые поствляются с гэцэцэ и шлангом, открыты для чтения круглосуточно.
          Милости просим.

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

          Давай сравним твои попытки это описать:
          В современных реализациях стандартной библиотеки короткие строки хранятся прямо внутри указателя. То есть память не выделяется в куче, а скопировать такую строку — всё равно, что скопировать целое число.


          И реальность:
          Вместо(поверх) капасити + локальный кеш. Скопировать такую строку всё равно, что скопировать строку.

          На остальное, как я понял — тебе ответить нечем? Я даже не удивлён.


          1. izvolov
            27.05.2016 08:47
            +4

            Дорогой друг, вместо ответа позвольте поинтересоваться Вашим опытом в языке C++ (в профиле это не указано). И покорнейше прошу — если, конечно, для Вас это не составит труда — показать примеры Вашего кода на данном языке.


            1. agent1319
              27.05.2016 10:20
              -8

              Слив засчитан. Ничего иного и не ожидалось.


              1. 23rd
                27.05.2016 10:59
                +2

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


                1. agent1319
                  27.05.2016 11:10
                  -6

                  Оценить моё понимание темы можно по моим постам — этого достаточно. Усомнившийся может поспорить. Аргументацией вида «выкатывание знамений» я не занимаюсь.


                  1. Chaos_Optima
                    27.05.2016 12:37
                    +5

                    По вашим постам получается что вы С++ вообще не владеете, либо вообще не понимаете его. сказать что raii не состоятельно, это очень глупо. Вам почти никто не отвечает, потому что трудно понять тот бред который вы пишите. Вы похоже не понимаете разницу между копированием и передачей владения. Строка не умеет в сишную строку 0_о простите а string().c_str() для чего?

                    Чё? Это невозможно. Можно пруфцы?

                    Вы точно про С++ говорите? Вот пример элементарной реализации подобного http://cpp.sh/4ufd


                    1. agent1319
                      27.05.2016 13:15
                      -5

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

                      сказать что raii не состоятельно, это очень глупо.

                      Почему же? Т.е. мне говорить нельзя, а вам можно? Л — логика.
                      Вы похоже не понимаете разницу между копированием и передачей владения.

                      И действительно:
                      Почему в С++ вообще существует разница между копирование объекта и полей? Правильно — причина в самом С++, а вернее в raii. Т.е. перемещение является кастылём для raii, но никак не какой-либо оптимизацией.

                      Да и сам новый тип ссылок решает 2проблемы — отсутствие возможности передать r-value по не константной ссылки, а так же новая перегрузка операторов/конструкторов. Всё это нужно из-за всяких раишных понятий владения.


                      Строка не умеет в сишную строку 0_о простите а string().c_str() для чего?

                      О боже, ну если не понимаете о чём речь — зачем лезть? Речь идёт о том, что строка должна владеть строкой, т.е. строка не может содержать в себе си-строку, только её копию. Это исходит и из контекста string_view, и из «часть строки» — хотя зачем я это пишу.

                      Вы точно про С++ говорите?

                      Я уже выше отвечал на этот вопрос, но похоже вам нужно только болтать.

                      Я там не вижу чтобы что-то хранилось в «указателе». По ссылке уб. Про реальные имплементации стл я уже писал:
                      https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L120

                      Все операции идентичны и копирование то же.


                      1. Chaos_Optima
                        27.05.2016 14:23
                        +3

                        Где я врал? Я лишь сказал, что по моему мнению вы не разбираетесь в С++ либо троль.

                        Почему же? Т.е. мне говорить нельзя, а вам можно? Л — логика.

                        Я не утверждал, что вам нельзя говорить, я сказал что так говорить глупо. Л — логика
                        Почему в С++ вообще существует разница между копирование объекта и полей? Правильно — причина в самом С++, а вернее в raii. Т.е. перемещение является кастылём для raii, но никак не какой-либо оптимизацией.

                        Вот ту объясните пожалуйста как вы связали копирование и raii? Просто судя по тому что вы пишите вы не понимаете разницу между копированием и передачей владения. Например string является абстракцией над строкой (ваш кэп) следовательно, когда мы копируем строку мы хотим скопировать именно строку а не указатель на неё. Копирование объекта и копирование полей различны, именно для того чтобы создавать логичное поведение, а не для raii. Перемещение по сути является синтаксическим сахаром, для объектов которые должны просто передавать владение, и опять же это никак не связанно с raii. Исключительно для того чтобы и писать было удобно и лишние действия не происходили (тобишь для оптимизации)
                        string get_some()
                        {
                          ......
                          return  some_str;
                        }
                        

                        строка не может содержать в себе си-строку, только её копию.

                        эм… берёте инструмент и обвиняете его что он не выполняет функции другого инструмента? Отлично.
                        Я там не вижу чтобы что-то хранилось в «указателе».

                        Значит вы не знаете С++, рас не понимаете как работает union
                        По ссылке уб.

                        Замените 8 на sizeof(char*) и не будет никого ub.
                        Про реальные имплементации стл я уже писал:

                        Вы написали что это невозможно я привёл вам контр пример, а то что вы привели gcc stl так реализаций то много, вы уверенны что все пишут только так?


                        1. agent1319
                          27.05.2016 15:59
                          -5

                          Я не утверждал, что вам нельзя говорить, я сказал что так говорить глупо. Л — логика

                          Но не сказал почему( и проигнорировал этот вопрос) — вывод — балабол.

                          Вот ту объясните пожалуйста как вы связали копирование и raii?

                          Во-первых дёрганье из контекста. Во-вторых — что же ты спастил одно, а не спастил другое? Ладно, ты вроде вменяемый и реально тут не понимаешь, а не юлишь как твои собратья.

                          Например string является абстракцией над строкой (ваш кэп) следовательно, когда мы копируем строку мы хотим скопировать именно строку а не указатель на неё.

                          Не верно — строка является интерфейсом к данным. Когда мы копируем интерфейс — мы копируем интерфейс. Даже если применить твоё понимание — нам нужна в строке идентичная информация, а не сам факт копирования.

                          Указатель — это интерфейс. Строка — это интерфейс. А данные — это данные. От копии строки нам надо только то, чтобы мы могли получить те данные, что хранились там до копирования.

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

                          Далее, во вменямых концепциях интерфейс доступа к данным и сами данные разделены. Они разделены на уровне си, который есть основа крестов. Есть данные — это массивы, хип и прочее, а есть объекты — это структуры, базовые типы и прочее. По этой причине данные в си/крестах не-копируемые, объекты и базовые типы копируемые. Память копируется отдельными средствами.

                          В логике языка, если объект не наследует память — он ею не владеет. При этом по логике здравой интерфейс доступа никакого отношения к тому, к чему у него есть и владеть этим чем-то не должен. В реальности же строки и владеет только интерфейсом, поэтому всё владение памятью — это заморочки раии. Т.е. риии не даёт взять кусок строки, не даёт сделать копию интерфейса — копия интерфейса делается через кастыль «мув-семантику». В крестах через 20лет до этого допрёли — молодцы, только это ничего не меняет.

                          И вменяемая концепция выглядит так: есть память, а есть интерфейс. Интерфейс отдельно — память отдельно. Это даёт возможность без убогих кастылей использовать разную память, что сейчас невозможно. Интерфейс копируется как интерфейс. Память копируется как память. Хочешь копию строки? Создай копию памяти и отдай её интерфейсу.

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

                          В конечном итоге что мы имеем — невозможность сделать копию интерфейса — это проблема крестовой строки, которая вызвана раии(т.к. она должна им владеть) — для этого собственно и сделали интерфейс без владения. Из этого всего следует, что копирование только интерфейса не теребует никакой мув-семантики, а все «оптимизации» которые принесла мув-семантика являются ничем иным, как костылём для копирования интерфейса.

                          эм… берёте инструмент и обвиняете его что он не выполняет функции другого инструмента? Отлично.

                          О боже — это не другой инструмент — это часть strings library, такая же, как и сам класс string. А в часть самой строки почему она не может?

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

                          Значит вы не знаете С++, рас не понимаете как работает union

                          О боже, и как же работает юнион? И да, причём тут юнион, если ты хранишь в указателе? Дак и храни в указателе, а не в юнионе.

                          Замените 8 на sizeof(char*) и не будет никого ub.


                          Я не придираюсь к херне. Будет — в юнионе.

                          Вы написали что это невозможно я привёл вам контр пример, а то что вы привели gcc stl так реализаций то много, вы уверенны что все пишут только так?

                          Говорилось именно про шланг и гцц. Опять же — враньё, вернее попытка игнорировать факт «копируется как число», вот шланг:

                          const_pointer __get_short_pointer() const _NOEXCEPT
                          {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}


                          В гцц анологично. Копируется как строка.

                          Потуги с «указателем» — являются такими же манипуляциями и враньём, ибо говорилось «в указателе», но потом понятие поменялось и стало «в массиве в юнионе», что можно трактовать как «вместо указателя».

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


                          1. Chaos_Optima
                            27.05.2016 16:55
                            +2

                            Но не сказал почему

                            Практически все классы все фрэймворки, api используют raii так что вполне очевидно что утверждать о не состоятельности raii глупо.
                            Во-первых дёрганье из контекста.

                            а что контекст как-то меняет то факт что вы связываете оператор копирования и raii? По моему нет, так что я жду ответа.
                            … И вменяемая концепция выглядит так: есть память, а есть интерфейс. Интерфейс отдельно — память отдельно.....

                            Вы вообще не понимаете концепцию ООП где пользователь оперирует объектами, а не отдельно памятью отдельно интерфейсом. Объект это совокупность данных и интерфейса по работе с этими данными, это единое целое. Копия объекта это копия как интерфейса так и данных. В концепции ООП у пользователя вообще не должно быть прямого доступа к данным, о каком разделе интерфейса и памяти ту вообще может идти речь?
                            И да
                            В логике языка, если объект не наследует память
                            WAT!? Что я бред, о каком языке вы вообще говорите?
                            А в часть самой строки почему она не может?

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

                            Один и тот же кусок памяти под разные переменные. Ок если вы не умеете union то вот альтернатива http://cpp.sh/6pyld
                            Потуги с «указателем»....

                            Смотрите пример выше, уже без юниона


                            1. agent1319
                              27.05.2016 18:50
                              -7

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

                              Во-первых, уже после 5-го класса дети не верят в аргумент «все не могут ошибаться». Зачем ты мне его выкатываешь?

                              Во-вторых, говорилось о нестоятельности раии в контексте строк, копирования и прочего в контексте производительности. Что там у тебя и как используется — меня мало волнует.

                              , а что контекст как-то меняет то факт что вы связываете оператор копирования и raii? По моему нет, так что я жду ответа.

                              Ответ был, но опять пошли потуги врать.

                              Не верно — строка является интерфейсом к данным. Когда мы копируем интерфейс — мы копируем интерфейс. Даже если применить твоё понимание — нам нужна в строке идентичная информация, а не сам факт копирования.

                              И далее по тексту всё разжевано.

                              Вы вообще не понимаете концепцию ООП где пользователь оперирует объектами, а не отдельно памятью отдельно интерфейсом.

                              Меня не волнуют твои взывания к ООП и прочим мантрам, заклинаниям. Я тебе описал альтернативную концепцию, которая оптимальней и проще. Есть что возразить — валяй, а нет зачем ты мне пишешь «твоя альтернативная концепция не соответствует моей концепции» — естественно, на то она и альтернативная.

                              Объект это совокупность данных и интерфейса по работе с этими данными, это единое целое.

                              Подожди, а string_view — это не объект? Зачем его впилили? Наверное за тем, что аришная строка показала свою полную несостоятельность?

                              Копия объекта это копия как интерфейса так и данных.

                              Копия интерфейса — это копия интефрейса. Копия данных — это копия данных. Почему вдруг у тебя интерфейсы-итераторы не владеют объектами, стримы не владеют объектами — как же так?

                              Это типичные дыры в представлении, но ты как рядовой верующий это пытаешься как-то оправдать. У нас есть объект — это данные(в данном случае строка) + интерфейс доступа к ним и операции над ними. Но ведь суть stl — это разделение данных и операций. У нас есть итераторы, которые такие же интерфейсы в данным. У нас есть алгоритмы, которые так же интерфейсы к операциям над даннымы и у нас есть строка, которая то же интерфейс к данным.

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

                              В концепции ООП у пользователя вообще не должно быть прямого доступа к данным, о каком разделе интерфейса и памяти ту вообще может идти речь?

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

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

                              WAT?! Что я бред, о каком языке вы вообще говорите?

                              В логике си и С++. Любая «память» является не-копируемой. Память сама по себе, кроме случаев, когда она является частью объекта(массивы в тех же структурах). Но опять же — они не копируемые — копируемые сами объекты.

                              А в часть самой строки почему она не может?

                              Потому что другой функционал, другие требования, другое предназначение. Потому это и является совершенно другим инструментом.

                              Слив засчитан. Предназначение идентично. Является частью одной библиотеки, но интегрирован только в одну строну — string_view — интегрирует в обе. Твоя вера и оправдания смешны.

                              И какой же там другой функционал, какие такие другие требование, какое-такое предназначение? Отвечай, а не балаболь.

                              Один и тот же кусок памяти под разные переменные.

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

                              Ок если вы не умеете union то вот альтернатива http://cpp.sh/6pyld

                              Опять же где тут «в указателе» — я не вижу. Ладно, давай специально для ламерков я поясню.

                               template <typename Tc, Tc… chars> constexpr void * operator""_to_pointer() {  constexpr size_t len = sizeof...(chars); uintptr_t ret = 0;  static_assert((len < 7) && (__BYTE_ORDER == LITTLE_ENDIAN) && (__CHAR_BIT__ == 8) && (sizeof(0ul) == sizeof(uintptr_t)) && (sizeof(uintptr_t) == 8), "");  return (void *)((uintptr_t[]){(ret |= ((chars & 0xfful) << (len * 8 + 8)), ret >>= 8)..., (ret |= (len & 0xff)), ret}[len + 1]);}  


                              Вот в указателе, а то, что у тебя «не в указателе».

                              Смотрите пример выше, уже без юниона 


                              О боже, почитай в словаре значение слова «значение», а потом научись отличать «в жопе» и «вместо жопы"/«по месту жопы». Давай ещё раз ссанина может быть в банке, вместо воды, но никак не в вводе. Ты вылили воду из банки — налил ссанину и говоришь — «ну вот ссанина в воде» — нет, ссанина не вводе — она вместо воды.


                              1. Chaos_Optima
                                27.05.2016 19:24
                                +3

                                Во-первых, уже после 5-го класса дети не верят в аргумент «все не могут ошибаться». Зачем ты мне его выкатываешь?

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

                                Простите но у вас там чушь была про наследование памяти. Так что ответа вы так и не дали, по крайней мере я его там не нашёл, перефразируйте.
                                Меня не волнуют твои взывания к ООП и прочим мантрам, заклинаниям. Я тебе описал альтернативную концепцию, которая оптимальней и проще.
                                Есть что возразить — валяй, а нет зачем ты мне пишешь «твоя альтернативная концепция не соответствует моей концепции» — естественно, на то она и альтернативная.

                                XDDD Да действительно, и пофиг что всё классы стл написаны в ООП стиле, они неправильные, потому что всё должны писать только в моём правильном стиле XD отлично, на этом в принципе можно разговор и окончить, но вы слишком забавны так что продолжим.
                                В логике си и С++.
                                Приведите пожалуйста пример наследования памяти в С++, ну или в любом другом языке, мне прям интересно.
                                Предназначение идентично… И какой же там другой функционал, какие такие другие требование, какое-такое предназначение?
                                эм… где же? string это контейнер и предназначен для полноценной работы со строками, sring_view это посетитель предназначен исключительно для просмотра содержимого и то с довольно строгими ограничениями.
                                Общее у них только возможность просмотра. Концептуально, они разные.
                                Отвечай, а не балаболь.

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

                                эм… Что в вашем понимании указатель? Для меня это кусок памяти в котором хранится адрес памяти, а для вас?
                                Вот в указателе, а то, что у тебя «не в указателе».

                                Можете дать ссылку с примером, например в http://cpp.sh/ или в ideone.com
                                О боже, почитай....
                                ох знатно бомбануло.
                                Чем конкретно моё решение отличается от вашего? Кроме того что оно компайлтайм и с проверками?


                                1. agent1319
                                  28.05.2016 17:22
                                  -6

                                  Так мы смотрим объективно или субъективно? Вы то пока не сказали по какой причине raii не состоятельно.

                                  Я написал причины — игноришь я могу начать не позволять тебе этого делать. Хочешь чтобы я продолжил с тобою играть — веди себя вменяемо.

                                  Ну и да причём тут вера? По факту все используют, а значит фича востребованна.

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

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

                                  Не состоятельной она была бы если бы её никто не использовал, как например старый auto.

                                  О боже, что же вы все такие тупые. У неё нет альтернативы — естественно её используют. Толку говорить о каком-то выборе, если выбора нет? В крестах изначально раии-контейнеры определялись как полноценные, поэтому не вводили никаких не-раишных контейнеров — сейчас введением вменяемых «контейнеров» она косвенно согласились с неполноценностью раии. Но у ламерков уже есть оправдание — string_view — это для тех, кто не осилил мув-семантику. Уровень некомпетентности рядового крестового балабола меня просто поражает.

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

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

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

                                  Изначально контекст был «не забыть об оптимизации», далее автор коммента продолжил его «стл оптимизированная — ко-ко-ко». И в этом контексте все утверждения озвучивались. Сейчас ты, как и любой ламерок, пытаешься съехать на «автоматическое управление ресурсами удобно для низкоквалифицированной силы, либо для быстрой разработки дерьма», но контекст был не в этом. Давай ещё проще, контекст был в ориентации на ТТХ конечного продукта, а не на простоту разработки, её дешевизну, доступность кадров и прочее.

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

                                  Простите, но у вас там чушь была про наследование памяти.

                                  Опять ты, амёбка, мне пытаешься врать и юлить. Если там чушь — докажи и покажи где, а так своим высером ты можешь только подтереться.

                                  Так что ответа вы так и не дали, по крайней мере я его там не нашёл, перефразируйте.

                                  Опять же — вранье. Не дал — докажи, не нашел — докажи, что его нет. Нахрен ты мне врёшь? Повторюсь ещё раз — если ты не разбираешься в теме — зачем ты споришь?

                                  Меня не волнуют твои взывания к ООП и прочим мантрам, заклинаниям. Я тебе описал альтернативную концепцию, которая оптимальней и проще.
                                  Есть что возразить — валяй, а нет зачем ты мне пишешь «твоя альтернативная концепция не соответствует моей концепции» — естественно, на то она и альтернативная.

                                  XDDD Да действительно, и пофиг что всё классы стл написаны в ООП стиле, они неправильные, потому что всё должны писать только в моём правильном стиле XD отлично 

                                  Опять эти глупые потуги. Ты реально думаешь, что ссылаясь на свои обезьяньи поверья ты сможешь меня поймать? Читая мне мантру про ООП — думаешь, если она в твоём стаде популярно — её не покрыть? Такая глупая и наивная балаболка.

                                  Я уже говорил — твои потуги могут производить(хотя куда там производить — ретранслировать) логику уровня «насекомое» и в стае подобных тебе ты можешь крыть других насекомых, но проблема в том, что как бы ты не пытался меня двигать — это невозможно по определению.

                                  Давай я тебе покажу почему твои потуги тщетны.Изначально нигде не говорилось о том, что что-то должно быть ООП(ну в твоём понимании его — ты ведь не объяснишь почему моя концепция не ООП, но это такое). Говорилось о разработки на результирующие качество кода с т.з. ТТХ. Далее утверждалось, что текущие стл итак максимально «быстр», но я объяснил и показал почему это не так. Из этого косвенно следует, что стл максимально быстр для той концепции, которую он реализует, а значит сама концепция является не годно в контексте «оптимизации».

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

                                  На этом, если я тебя спрошу «на чём» — ты обделаешься, поэтому что-то кукарекать не советую. Да и куда тебе продолжать, ты уже понимаешь что попытка твоя провалилась.

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

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

                                  http://ideone.com/MBD86P

                                  Собери(попытайся) вменямым компилятором это сам — так помойка на ideone не может в мой код.

                                  эм… где же? string это контейнер и предназначен для полноценной работы со строками, sring_view это посетитель предназначен исключительно для просмотра содержимого и то с довольно строгими ограничениями.

                                  Интерфейс просмотра содержимого — это 


                                  1. Bronx
                                    28.05.2016 23:10
                                    +1

                                    > Мой обычный стиль куда более агрессивен чем то, что ты видел.

                                    Луговский, ты?! :)


                                    1. Yuuri
                                      29.05.2016 13:17
                                      +5

                                      Скорее, Царь Сишки aka Superhackkiller1997.


                                  1. Chaos_Optima
                                    29.05.2016 01:11
                                    +1

                                    XD Ох знатно я поржал, спасибо, сохраню для памяти.

                                    Если ты думаешь, что у меня бомбануло — это твоя проблема. Мой обычный стиль куда более агрессивен чем то, что ты видел.
                                    Ох бедные люди что с тобой общаются, хотя с тобой наверно никто и не общается. Ну или в реале ты более сдержан или давно бы отхватил.
                                    По факту получается, что ты не объяснил по какой причине raii не состоятельно, лишь утверждал что то-то то-то сделано для raii а raii не состоятельно, балабол? балабол. Слив засчитан.
                                    Наследование памяти вы не показали, а то что по ideone феерично, спасибо буду как анекдот показывать.
                                    void * ptr = nullptr;//указатель
                                    auto ptr_ptr = &ptr;//указатель на память, в которой лежит указаль на воид.
                                    uintptr_t ptr_val = (uintptr_t)ptr;//значение указателя.
                                    //указатель — это интерфейс. Адрес — это его значение. Память — это память — //она к указателю не имеет отношения — с памятью его связывает операция разименования.
                                    //в указателе — это в значении указателя.

                                    Простите а значение указателя где хранится? Не в памяти ли? XD
                                    Прочитай в словаре значения слова «значение» и научись отличать содержимое от пространства.

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


                                    1. Chaos_Optima
                                      29.05.2016 01:24
                                      +1

                                      Да по твоему же гайду http://cpp.sh/5hyh


                                    1. agent1319
                                      29.05.2016 03:31
                                      -7

                                      XD Ох знатно я поржал, спасибо, сохраню для памяти.

                                      Ну что я могу сказать — для обделавшегося постоянное заострении внимания на том, что от кого-то воняет — типичная потуга.

                                      Ох бедные люди что с тобой общаются, хотя с тобой наверно никто и не общается.

                                      Те, кто обладают хоть каким-то развитием могут.

                                      Ну или в реале ты более сдержан или давно бы отхватил.

                                      От кого?

                                      По факту получается, что ты не объяснил по какой причине raii не состоятельно, лишь утверждал что то-то то-то сделано для raii, а raii не состоятельно, балабол? балабол. Слив засчитан.

                                      Совсем балаболка сломалась. Ну ничего — бывает. Там было все объяснено — я могу повторять это бесконечно и ты будешь врать, врать, в надежде, что мне когда-то надоест(хотя нет — достаточно хомячкам тыкать -1 и через неделю будет 1 пост в неделю, чего собственно слившиеся и добиваются).

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

                                      Показал. Хотя опять же — ситуация аналогичной той, что выше. Если тебе нечего возразить — этого уже достаточно для определения тебя как слившегося. С таким же успехом я могу говорить «показал» — дальше что?

                                      Простите, а значение указателя где хранится? Не в памяти ли? XD

                                      Причём тут где хранится — хранится представление значение и там всё это описано. Как ламерок слился с «в указатели» на «в памяти», ну бывает.

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

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

                                      А ваш пример про мочу необычайно ржачный. Можете побольше подобного написать? Очень прошу.
                                      Кстати приведите пожалусто пример использования вашего кода с переводом строки в указатель, а то он отказался компилится 

                                      Мои примеры иллитны и идеальны. В любом случае что бы ты не пытался из себя строить перед пацанами — сильнейший уже определился.

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

                                      «научителамеркавкод»_to_pointer (); — вот так.

                                      Да по твоему же гайду http://cpp.sh/5hyh

                                      http://cpp.sh/9pd4


                                      1. Chaos_Optima
                                        29.05.2016 09:58

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

                                        «научителамеркавкод»_to_pointer (); — вот так.
                                        Ты в cpp.sh код покажи, Так чтобы он компилировался и работал только. А то он пока не на что неспособен, а ты выглядишь как неудачник наложивший в штаны.
                                        http://cpp.sh/9pd4
                                        //потуги убоги — это просто эмуляций ещё одно мемкопи — т.е. копирование памяти через значение.

                                        Так в твоём же примере выше было что написано? //значение указателя.
                                        Получается от своих слов отказываешься? Ох и балаболка XD
                                        //когда дебил очень сложно думать и высирать что-то осмысленное.

                                        Ну по тебе заметно, школьничек.


                                        1. agent1319
                                          29.05.2016 13:21
                                          -3

                                          Так и знал, эффект Даннинга Крюгера.

                                          Сразу забылось и раии и все остальное, ну бывает.

                                          Ты в cpp.sh код покажи, Так чтобы он компилировался и работал только. А то он пока не на что неспособен, а ты выглядишь как неудачник наложивший в штаны.

                                          Ламерок опять продемонстрировал свою никчёмность. Одни сливы, никаких внятных аргументов — «не способен» — почему? На основании чего я «выгляжу как неудачник»? На эти вопросы нет ответов, да и не будет.

                                          А судя по тому, что днище даже мою ошибку не заметило — ну дело такое. https://godbolt.org/g/pgLZR3

                                          Так в твоём же примере выше было что написано? //значение указателя.

                                          И? У тебя-то не используется значение указателя — значение используется для копирования памяти.

                                          Строка пишется в char[], читается из char[] — указатель там форфан и ничего не делает. У меня же функция возвращает именно значение.

                                          Получается от своих слов отказываешься? Ох и балаболка XD

                                          От каких слова я отказываюсь? Поподробней.

                                          В целом потуги амёбки ясны — пытается что-то там мне балаболить, ловить, сама понимает что это бесполезно, но на что-то надеется.

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

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


                          1. Chaos_Optima
                            27.05.2016 18:13

                            Я не придираюсь к херне. Будет — в юнионе.

                            А можете скинуть кусок стандарта который говорил бы что это UB. Ну или своими словами почему это UB.

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


                            1. agent1319
                              27.05.2016 19:10
                              -2

                              § 9.5

                              In a union, at most one of the non-static data members can be active at any time, that is, the value of at
                              most one of the non-static data members can be stored in a union at any time.


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

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

                              Алгоритмы — это операции над данными, при этом данные представляются в виде обобщенного инстерфейса доступа(который данными не владает).

                              Итераторы — интерфейсы доступа. string_view — интерфейс доступа. Адаптеры — интерфейсы поступа. И «контейнеры» должны быть интерфейсами доступа.

                              Но с этим проблема — универсального представления данных нет и нам надо было бы городить 10разных хранилищ данных. По этой причине и родился этот больной симбиоз.

                              А это данные отдельно — это некстген, авось когда-то в крестах до этого допрут, как допёрли до string_view — хотя это и заняло 20лет. И получается — у тебя множество аллокаторов — нужна строка с кешом? Взял буфер с кешом, указал размер кеша — вкатил его в строку — идельно. Далее авось осилятся инстансы аллокатора. Это ООП, а то что у тебя — кастыли


                              1. Chaos_Optima
                                27.05.2016 19:30
                                +2

                                § 9.5...
                                И? Где тут про UB?
                                А это данные отдельно — это некстген
                                А ну раз некст ген то ок, мужики то не знали XD
                                И получается — у тебя множество аллокаторов — нужна строка с кешом? Взял буфер с кешом, указал размер кеша — вкатил его в строку — идельно. Далее авось осилятся инстансы аллокатора. Это ООП, а то что у тебя — кастыли
                                О да ООП оказывается завязано на работе с аллокаторами, прикольно. А то что stl контейнерам можно указывать свои аллокаторы вы походу не в курсе?


                                1. agent1319
                                  27.05.2016 20:42
                                  -4

                                  И? Где тут про UB?

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

                                  А ну раз некст ген то ок, мужики то не знали XD

                                  Потуги ламерков меня не волнуют — есть что возразить — пытайся.

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

                                  Да, завязано. Хотя мне уже надоела что-то пытаться объяснить ламеркам. Принцип ООП — это построение конечных объектов из набора объектов. И аллокатор это такая же часть объекта, как и не аллокатор.

                                  А то что stl контейнерам можно указывать свои аллокаторы вы походу не в курсе?

                                  О боже, убогое днище. Зачем ты мне это пишешь? Я где-то разве писал, что нельзя? Я там писал про интансы аллокатора, хотя опять же — сходи в словарь я не обязан каждый раз ламерку что-то объяснять.


                                  1. Chaos_Optima
                                    28.05.2016 11:39
                                    +7

                                    Мда… Вы ведёте себя как очень агрессивный школьник, который несёт дикий бред, явно по причине своей полной безграмотности, как в плане орфографии, так и в плане программирования, но зато полностью уверены что крутой спец (эффект Даннинга Крюгера по видимому). И ещё удивляетесь почему вам никто не отвечает и минусуют. Было весело ;7 с вами пообщаться.


                      1. elmm
                        27.05.2016 14:35

                        Я там не вижу чтобы что-то хранилось в «указателе». По ссылке уб. Про реальные


                        а юнион с _M_local_buf по вашей же ссылке по что???


                        1. izvolov
                          27.05.2016 15:05
                          +1

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


                          Но:


                          1. Она используется для строк в кланге.
                          2. В самом гэцэцэ она используется в experimental::any.


                          1. agent1319
                            27.05.2016 16:27
                            -2

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


                        1. agent1319
                          27.05.2016 16:10
                          -4

                          Вы действительно думаете, что вы видите там что-то, что не вижу я?

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

                          Далее, опять же — все как-то забыли про «копируется как число», чего нигде нет.

                          В конечном итоге буфер замещает некоторые поля(копасити + хвост в гцц, а в шланге все 3поля), копирование происходит так же.

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


                  1. agent1319
                    27.05.2016 12:43
                    -4

                    Ну чё, как я понял все слились? Что же такие слабенькие — может найдётся тот, кто сольётся хотябы на 3-ем ответе, а не на втором.


      1. esil
        27.05.2016 01:59
        +7

        Вам ставят минусы и никто не отвечает, потому что вы несете какой-то откровенный бред из лозунгов. Вот например: «Возьмём гццешную стл(одно из самых, если не самая) — является не более, чем генерик-интерфейсом к glibc». Основная часть STL — это стандартные контейнеры и алгоритмы. О каком использовании glibc в них вы вообще говорите?


        1. agent1319
          27.05.2016 11:04
          -7

          Нет, мне ставят минусы не поэтому. Я не написал ни единого лозунга. Ваше восприятие показывается обратное, ведь именно у вас идёт отторжение всего, что не соотносится с линией партии. Никто так и не смог внятно ответить без вранья, передёргивания — почему? Выиграть и поймать того, кто говорил лозунгами проще простого, но где всё это? Почему все попытки автора поста не увенчались успехом и он попросту слился? И как раз-таки это прямой показатель того, кто говорит лозунгами и поверьями, а кто воспринимает мир реально.

          По поводу лозунгов — ты мои мне не предоставишь — я даже спрашивать не буду, а вот лозунги моего оппонента я представлю: «Не осилил» — типичное оправдание и аргумент против любого несогласного с линией партии. «Всё оптимизировано — всё идеально» — такой же типичный лозунг, который оправдывает любые претензии к качеству кода у популярных. Это два основных посыла.

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

          Утверждающий попытался защитить миф про мув-семантику — не смог. Попытался защитить свой звон — не смог.

          Ну зачем же так откровенно врать.

          Основная часть STL — это стандартные контейнеры и алгоритмы.

          Это не важно, ибо в основном посте говорилось о строках и стримах, автор того поста отвечал говоря об стл — есть претензии — выкатывайте их ему, а не мне. Я интерпретирую стл как libc++ — претензии не ко мне.

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

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

          Так же я пояснил и по поводу интерфейса приведя в пример мертворожденный valarray. Любые оптимизации интерфейса и структур данных, унификации алгоритмов над ними не приживаются в «современном С++», ибо оптимизация там не нужна — все о ней кричат, но не более того.

          О каком использовании glibc в них вы вообще говорите?

          Повторюсь ещё раз, в статье говорилось об строках/стримах все претензии к автору поста на который я отвечал. Далее, я отвечал на «оптимизированный по гланды стл», а то, что ты описываешь не является оптимизированной частью стл. Ну и даже про неё я написал, а все твои придирки не более, чем враньё и попытки поймать меня, что является заведомо тщетным.


          1. esil
            27.05.2016 11:27
            +4

            Ага, отлично, значит речь шла о строках и стримах.

            Во-первых, что же там такое в этих строках libstdc++ используется из glibc, что вы их называете «не более, чем генерик-интерфейсом к glibc»?

            Во-вторых, вместо того, чтобы просто дать конкретный ответ вроде «извините, со всей libstdc++ я погорячился, я имел в виду только что строки и стримы явзяются генерик-интерфейсом к glibc», вы выкатили какую-то просто невероятную простыню из потока сознания про какую-то генеральную линию партии. За это и минусы.


            1. agent1319
              27.05.2016 12:28
              -4

              >>Ага, отлично, значит речь шла о строках и стримах.
              Враньё. Речь шла обо всём, а тот факт, что я обобщил stl до всей libc++ — это не моё допущение, а автора комментария.

              >>Во-первых, что же там такое в этих строках libstdc++ используется из glibc, что вы их называете «не более, чем генерик-интерфейсом к glibc»?
              Строка определяется операциями, из которых все(которые пахнут оптимизацией) являются обёртками над string/mem/io из либц.

              https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/char_traits.h#L231

              https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L5409

              Во-вторых, вместо того, чтобы просто дать конкретный ответ вроде


              Нет, в прочем игнор показателен. Я объяснил почему и от чего взялись стримы/строки в стл — вы это написали автору оригинального коммента? Ведь нет?

              вы выкатили какую-то просто невероятную простыню из потока сознания про какую-то генеральную линию партии. За это и минусы.

              Как же я люблю это враньё. Я там выкатил не только изобличение вашей мотивации, но и по теме стл — т.е. контейнеров и алгоритмов. Это было проигнорировано, чего и следовало ожидать — т.к. коммент написан был не с целью разобраться/объяснить etc, а с целью поймать, что явно не удалось. И не удастся по банальным причинам объективной силы.


              1. esil
                27.05.2016 12:44

                Враньё. Речь шла обо всём, а тот факт, что я обобщил stl до всей libc++ — это не моё допущение, а автора комментария.

                Еще раз. Какое именно использование glibc внутри STL вы имели ввиду, когда говорили «не более, чем генерик-интерфейсом к glibc»? В предыдущем своем посте вы сказали, что это относилось только к строкам и стримам. Теперь опять появилось «речь шла обо всем». Вы путаетесь в показаниях.

                Строка определяется операциями, из которых все(которые пахнут оптимизацией) являются обёртками над string/mem/io из либц.

                Ну вот, оказалось, что «строки являются оберткой над glibc» превращается в «операции конверсии строк в числа являются обертками над glibc». Ну здравствуйте, капитан очевидность. И сразу все высказывание теряет значимость, потому что очевидно всем и ни на что не влияет.


                1. agent1319
                  27.05.2016 14:02
                  -3

                  Еще раз. Какое именно использование glibc внутри STL вы имели ввиду, когда говорили «не более, чем генерик-интерфейсом к glibc»?


                  Опять попёрло враньё. Я жду либо ответа на:

                  Это не важно, ибо в основном посте говорилось о строках и стримах, автор того поста отвечал говоря об стл — есть претензии — выкатывайте их ему, а не мне. Я интерпретирую стл как libc++ — претензии не ко мне.


                  Изначальный посыл был:
                  Со временем C++ превратился из «быстрого» языка в «функциональный», и о производительности забыли. Сейчас уже ни для кого не секрет, что некоторые компоненты C++, например, библиотека iostream и строки, в силу своей природы не могут работать быстро; кроме того, отсутствуют некоторые основные возможности вроде управления передачей данных по сети и совсем уж базовые функции, например, простейшая процедура разбиения строк.


                  Ответ на это был на «о производительности забыли»:

                  Наверное, поэтому весь STL заоптимизирован по самые гланды, чтобы при каждом удобном случае вызвать наиболее эффективную операцию.


                  При этом нигде в изначально посте об STL(как только о контейнерах) не говорилось, а примеры были из не из аlgorithms/сontainers library, а из strings/io, но автор изначального комментария начал говорит об стл. На основании этого я могу обобщить stl по любой из списках библиотек, а не только аlgorithms/сontainers.

                  В предыдущем своем посте вы сказали, что это относилось только к строкам и стримам.

                  Не говорил. Я сказал:

                  Далее, я отвечал на «оптимизированный по гланды стл», а то, что ты описываешь не является оптимизированной частью стл.


                  Т.е. утверждая это я под этим имел ввиду только ОПТИМИЗИРОВАННУЮ часть стл, в которую аlgorithms/сontainers не входят(а их части являются такой же обёрткой, ну которые реально оптимизированы). Я это спокойно могу вывести и у тебя не найдётся ничего, чем ты сможешь мне возразить. Поэтому я не советую играться со мною, пытаться меня поймать — это глупая и непосильная задача для текущих моих оппонентов.

                  Теперь опять появилось «речь шла обо всем».

                  Враньё. Я такого не говорил.

                  Было сказано, что в посте в целом речь шла обо всём и в частности об аlgorithms/сontainers library. Ты спастил кусок и пытается врать, игнорируя сей факт.

                  Вы путаетесь в показаниях.

                  Так мило. И в чём же конкретно.

                  Ну вот, оказалось, что «строки являются оберткой над glibc» превращается в «операции конверсии строк в числа являются обертками над glibc».

                  Враньё.

                  https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/char_traits.h#L231

                  Где же тут «операции конверсии строк в числа»? Я жажду их увидеть.

                  https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L5409

                  Где же тут ТОЛЬКО «операции конверсии строк в числа»? Я жажду их увидеть.

                  Далее, разносить так разносить:

                  Стандарт определяет strings library как:

                  This Clause describes components for manipulating sequences of any non-array POD (3.9) type


                  Где компоненты есть:
                  The following subclauses describe a character traits class, a string class, and null-terminated sequence
                  utilities


                  В которых null-terminated-операции есть либц, string class есть обёртка над character traits, а character traits я уже выкатил.

                  Ну здравствуйте, капитан очевидность.

                  Хорошо, ладно — оставим балабольства и сливы выше. Значит всё обёртки, но при этом «STL» оптимизирована? Либо оптимизирована либц? Надо уж определиться в показаниях.

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

                  Попытки юлить такие пытки. Я уже не раз говорил подобным тебе, играться в следователей, ловить, иметь возможность что-то противопоставить — это всё работает только в вашем окружении, т.к. вы собираетесь +-1% от среднего уровня развития сообщества и вам начинает казаться, что вы действительно что-то можете — это не так. Глупо искать брешь в моей логике т.к. она совершенно иного уровня. Вместо пустых попыток ко вранью лучше бы попытался провести внятный анализ моего поста и оспорить его. Я даже тебе растолкую много непонятных слов/кода и понятий.

                  Хотя потом тебя точно так же будут минусовать, но за всё надо платить.

                  Скучно. Качество аудитории активных спорщиков тут действительно никакое. Зря я решил что-то написать.


                  1. esil
                    27.05.2016 14:16
                    +4

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


                    1. agent1319
                      27.05.2016 16:21
                      -4

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


            1. agent1319
              27.05.2016 12:36
              -4

              Что мы видим. 3 оратора друг за дружкой слились, по-теме ничего предоставить не могут — одни переходы на личности, пакостят минусами, объективно слабы в той теме, о которой пытаются рассуждать. Чего вы пытаетесь добиться? Хотя я понял — тактика типичная для барьбы с более сильными регистрантами — минусовать в тёмную для того, чтобы оппонент вынужден был ретироваться, если не хочет остаться без рейтинга этого ресурса(или что там у вас). Не работает.


              1. saboteur_kiev
                29.05.2016 04:12
                +7

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


    1. chabapok
      31.05.2016 15:49
      -5

      " весь STL заоптимизирован по самые гланды"
      Оптимизация не может быть абстрактной. Она идет под конкретную задачу, и иногда даже под конкретное железо, то есть говорить, мол, заоптимизирован и точка — вообще некорректно.

      Не знаю как сейчас, но по состоянию на ~5лет назад (что не так и много для плюсов) натыкался на то, что std:vector аллоцировал по 1 элементу, и каждый раз при добавлении элемента делал фактически realloc с копированием данных. Это можно назвать оптимизацией по памяти, а хотелось по производительности, чтобы предаллоцировалось 10..20% от существующего размера. Наверное, если знаешь как — это тоже как-то делается, но навскидку решения не нашлось. В итоге решили не парить мозг, переписали все на java и от тормозов избавились.


      1. izvolov
        31.05.2016 16:21
        +3

        Оптимизация не может быть абстрактной

        1. Вызов memmove в алгоритмах вместо копирования или переноса тривиальных объектов — вполне себе абстрактная оптимизация.
        2. Концепция обобщённого программирования, по которой строилась СБШ, предполагает максимально общие конструкции, и при этом максимальную эффективность в каждом конкретном случае. Очень рекомендую ознакомиться.

        Возможно, утверждение "вся STL заоптимизирована" слишком сильное. Но оно не так уж и далеко от истины.


        std:vector аллоцировал по 1 элементу, и каждый раз при добавлении элемента делал фактически realloc с копированием данных

        Это невозможно. Стандартом установлена асимптотика выполнения метода std::vector<...>::push_back. Это амортизированное O(1).
        http://www.cplusplus.com/reference/vector/vector/push_back/


        Разве что у вас была какая-то левая/самопальная реализация стандартной библиотеки.


        переписали все на java и от тормозов избавились

        ;D


        1. chabapok
          31.05.2016 16:47

          Вроде стандартная «убунтовская», но какая именно — не помню. Помню, мы сильно удивились, когда нашли это. Сейчас наугад посмотрел какие-то исходники stl — удваивают размер при нехватке. Для нас такое б жирновато конечно, но все же лучше чем каждый раз +1 делать.
          Наверное, действительно унас была какая-то кривая реализация. Исследований других либ мы тогда особо не проводили.


          1. Antervis
            31.05.2016 17:23

            std::vector как раз и удваивает, скорее всего, другие контейнеры тоже. Рекоммендую не забывать про std::vector::reserve, хотя в рамках объемов оперативной памяти более 40 реаллокаций не сэкономишь


            1. maksqwe
              02.06.2016 00:38
              -3

              Помню этот вопрос рассматривали в рамках одного проекта где нужно было держать в кеше ооочень большое кол-во данных, где новый пуш_бек мог вызвать реаллокацию на большее значение нежели есть доступно. И для MSVC 2013 и GCC 4.6 (debian 6) показывали 1.5 коэффициент увеличения памяти в случаи ее нехватки, но нас такое не устроило и переписали аллокатор на свой собственный.
              По этой теме просто и доступно почему выбирается такой коэффициент можно почитать тут:
              http://stackoverflow.com/a/5232342


              1. Antervis
                02.06.2016 06:18
                +5

                а зачем писать целый аллокатор, если можно перед push_back написать if (v.capacity() == v.size()) v.reserve(v.capacity()*1.2 /*+100*/) или любой другой закон увеличения объема?


          1. Jester92
            01.06.2016 09:22

            Насколько знаю коэффициент увеличение памяти в зависит от компилятора std::vector::push_back. И советую пользоваться std::vector::reserve или std::vector::resize — это позволяет избавиться от лишних копирований содержимого вектора.


  1. Zifix
    25.05.2016 17:00
    +6

    У меня тоже есть ощущение, что с современным C++, что-то не в порядке. «Навороченный» код на шаблонах становится крайне сложно понимать и вдобавок, он не даёт обещанной эффективности. Я вообще все больше склоняюсь в сторону написания кода в стиле C++ с классами.
    Qt пошло по этому пути давным давно, и до сих пор хорошо себя чувствует.


    1. evilruff
      27.05.2016 06:31
      +2

      не флейма ради, но много лет программируя на Qt, после QString, std::string кажется просто издевательством над мозгом по удобству пользования и читаемости кода… наверное тут действительно кто к чему привык, и все что делает QString можно легко решить на std/boost но на самом деле при всей мега-супер-пупер гибкости в большинстве случаев рядовому программисту 99% различного рода абстрактых сущностей и приблуд нафиг не надо…

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


      1. CodeRush
        27.05.2016 20:46
        +1

        Я вот прямо сейчас пытаюсь решить задачу замены QString, QByteArray и QDir/QFile/QFileInfo на отдельные классы вне Qt, чтобы отвязать от нее свой движок для разбора файлов UEFI. И если с последними еще как-то можно справиться при помощи boost:fs, а второй эмулировать поверх std::basic_string<uint8_t>, то что делать с QString — решительно непонятно. На что заменить tr().arg()? Как сделать конструктор, принимающий форматную строку и переменное число аргументов, не занимаясь при этом велосипедостроением. Пока использую cbstring и его метод format, но это боль, кровь, кишки и переписывание тысячи строк кода.


      1. Antervis
        31.05.2016 17:25

        Qt идет по пути наращивания функционала, а стандарт c++ — в сторону универсальности и оптимальности, чтобы переделывать не приходилось.


  1. ditu
    25.05.2016 17:11
    -6

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


    1. khrisanfov
      26.05.2016 07:50
      +2

      А что за языки такие? Можно хотя бы один пример?


      1. Yuuri
        26.05.2016 12:59

        Призываются оберонщики в тред :)


        1. kemiisto
          26.05.2016 13:36

          Почему сразу «оберонщики»? Не Обероном единым. Есть и другие «языки-чемоданчики»: Smalltalk, Lua, Scheme. Правда, они динамически-типизированные. Из статически то типизированных кроме Оберонов, получается, что и нет ничего осязаемых размеров.


        1. prospero78su
          26.05.2016 21:42

          А что не так с Оберонами? Я как раз заканчиваю небольшой (12к строк) проект на нём родимом. Код проще, быстрей, надёжней.
          Работает как лом.
          А вот исполнение проекта на С++ было заведомо заказано.


          1. Yuuri
            27.05.2016 01:11
            +3

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


  1. kalexey8
    25.05.2016 17:11

    Я бы не сказал, что писать на verilog или vhdl сложнее чем на c++ скорее наоборот. На vhdl сложновато написать запутанный код. Можно сказать, что под ПЛИС в общем сложно написать запутанный код, если специально к этому не стремиться.


  1. Alexey2005
    25.05.2016 17:40
    +28

    У C++ есть ещё серьёзная проблема со сборкой проектов. Ни в одной другой экосистеме проект не обладает таким чудовищно высоким шансом не собраться на чужой машине. Если вы качаете C++ проект с Github'а, то почти наверняка с первого раза собрать его не получится, и придётся заниматься шаманством.


    1. GamePad64
      25.05.2016 19:13
      +3

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


      1. ZaMaZaN4iK
        25.05.2016 19:37
        +3

        а ещё, может быть, когда-нибудь будет пакетный менеджер…


      1. mapron
        25.05.2016 19:44
        +4

        Можете пояснить, каким образом модули решат эту проблему? Несобираемость проектов — скорее из-за платформенной универсальности, доставшейся от Си. Всяческие autoconf-ы и pkgconfig-и пытаются эту проблему решить не первый десяток лет с переменным успехом.


      1. OlegMax
        25.05.2016 23:17
        +2

        Модули — это 10%. Без стандартизации ABI в этом направлении далеко не уйти. Под Linux безумная морока с разными версиями stdc++ в разных дистрибутивах. Это не говоря про все прочие бинарные зависимости.


    1. bubokastor
      25.05.2016 22:27

      Ну это проблему должно решить модули который должны были выйти в c++ 17.


    1. dipsy
      25.05.2016 22:27

      да да, и куча разных малосовместимых «с++», не то что для разных платформ, а даже под одну, к примеру windows, но тут и с чистым си такая же проблема, в любой кросс-платформенной библиотеке #ifdef на #elif-е и assert-ом погоняет.


  1. romy4
    25.05.2016 17:57

    > ни для кого не секрет, что некоторые компоненты C++, например, библиотека iostream и строки, в силу своей природы не могут работать быстро;
    для автора, похоже, секрет писать так, чтобы работало быстро.


    1. metopa
      26.05.2016 21:42
      -1

      Ну iostream и правда не самый быстрый, хотя бы в силу того, что при каждой IO операции сначала конструируется sentry-объект. Но абсурдности текста это не убавляет.


      1. romy4
        26.05.2016 21:58
        +1

        iostream по скорости не отстаёт от обычного fread. У него проблемы с дизайном, но никак не со скоростью [1] [2]. Так что к С++, про что якобы намекает автор оригинальной статьи, это отношения не имеет.


        1. agent1319
          27.05.2016 03:14

          А причём тут fread? Автор намекает всё правильно, т.к. стримы — это форматированный ввод/вывод, а не аналог фриду. При этом они должены быть быстрее фрида. Да и с чего вдруг именно фрид? Фрид точно так же в силу своей природы быстро работать не может.

              -std=gnu++1z -march=native -O3 
          $ ./clang3.8 
          
          fread                   91.3046 91.3087
          fread w sbuffer         90.9951 91.1043
          fread w lbuffer         91.3046 91.2016
          read2                   69.7235 69.6309
          mmap                    149.131 149.874
          fancy mmap              149.964 149.343
          mmap (shared)           149.964 149.843
          fancy mmap (shared)     149.964 149.951
          Cpp                     95.1899 95.3484
          
          
          $ ./clang3.8 //-stdlib=libc++
          
          fread                   90.3823 90.274
          fread w sbuffer         90.3823 90.5862
          fread w lbuffer         90.3823 90.4556
          read2                   67.1089 67.0633
          mmap                    148.307 148.442
          fancy mmap              149.131 148.514
          mmap (shared)           148.307 148.627
          fancy mmap (shared)     149.131 148.941
          Cpp                     11.0741 11.069
          
          $ ./gcc61 
          
          fread                   139.086 138.678
          fread w sbuffer         136.957 137.351
          fread w lbuffer         137.659 137.376
          read2                   70.0876 70.2154
          mmap                    163.68 163.623
          fancy mmap              163.68 163.275
          mmap (shared)           162.688 162.45
          fancy mmap (shared)     161.708 162.297
          Cpp                     100.162 100.115
          


          Сливает фриду. Цифры ммап смотреть не имеет смысла, ибо бенчмарк упирается в убогую реализацию doSomeComputation(). В реальности же ммап быстрее на порядок.


  1. IvanPanfilov
    25.05.2016 18:16
    +5

    автор — ретроград.
    но С++ действительно ничего не поможет — поэтому нужно валить на rust


    1. ZaMaZaN4iK
      25.05.2016 18:18
      +2

      Крайне смелое заявление, что «нужно валить на rust». Чем-то подкрепить можете?


      1. IvanPanfilov
        25.05.2016 18:26
        +6

        https://www.rust-lang.org/faq.html#project

        What is this project's goal?
        To design and implement a safe, concurrent, practical systems language.

        Rust exists because other languages at this level of abstraction and efficiency are unsatisfactory. In particular:

        There is too little attention paid to safety.
        They have poor concurrency support.
        There is a lack of practical affordances.
        They offer limited control over resources.
        Rust exists as an alternative that provides both efficient code and a comfortable level of abstraction, while improving on all four of these points.

        https://habrahabr.ru/post/224607/

        https://habrahabr.ru/post/274757/


        1. kemiisto
          25.05.2016 23:27
          -1

          Концептуально, многое из этого было в той же Modula-3 ещё в 90-х, но не взлетело, как известно. За С++ уже тогда стояло столько бабла, что особых шансов то и не было. Нет их и сейчас. Только если за Rust возьмётся очень крупный игрок на рынке ПО, тогда шансы будут. А так, Rust небольшой hype нагонит, как уже было не раз, и канет в небытие.


          1. asdf87
            26.05.2016 07:50
            +12

            Концептуально, rust отличается очень сильно практически от всех современных и не только языков программирования. За счет концепций owning, borrowing и lifetimes он получает «полуавтоматическую работу» работу с памятью (на самом деле, с ресурсами вообще), т. е. сохраняется возможность достаточно низкоуровневой работы с памятью/ресурсами, но при этом компилятор во время компиляции программы может проверить корректность выполнения концепций owning, borrowing и lifetimes и там самым обеспечить очень высокую безопасность программ в плане работы с ресурсами (может быть не 100%, но очень близкую к ней) + это все достигается без использования GC, багодаря чему для программ на rust можно получить детерминированное управление ресурсами, высокую скорость, отсутствие гонок данных (за счет соблюдения основных концепций языка + отсутствия GC + еще немного контроля со стороны системы типов) и практически отсутствующий runtime, даже меньше чем у C++ (да, да у C++ тоже есть runtime). Все это несколько ломает мышление, особенно не для C++, и заставляет писать программы в другом стиле, но и дает большие преимущества за счет перекладывания большого пласта рутинной работы с программиста на компилятор.


            1. kemiisto
              26.05.2016 11:44
              -5

              (Полу)автоматическую работу с памятью (ресурсами) — это концепция, а GC, owning, borrowing и lifetimes — это всё уже детали реализации данной концепции. А то и всего-навсего buzzword'ы. Тоже самое касается и прочих концепций, вроде, безопасности типов и т.д. Hype, как я уже сказал будет, а вот будет ли что-то кроме него — вопрос. Вы не поймите меня неправильно, я только «за» эти концепции, детали реализации пока оставим в сторонке. Просто я трезво стараюсь смотреть на предмет «взлетит/не взлетит» и, как следствие, на «валить/не валить».


              1. Yuuri
                26.05.2016 13:08
                +3

                Не согласен насчёт деталей. «Безопасная работа с памятью без нагрузки на рантайм» – это концепция, и Rust вроде бы первый и единственный, кто сумел её реализовать.


                1. DarkEld3r
                  26.05.2016 13:16
                  +4

                  Есть ещё Cyclone, которым (среди прочих) Rust и вдохновлялся, но он никакого распространения не получил и является, по сути, "теоретическим экспериментом".


              1. DarkEld3r
                26.05.2016 13:14
                +5

                а GC, owning, borrowing и lifetimes — это всё уже детали реализации данной концепции

                Не согласен. Да, можно сказать, что GC — это просто "мелкая деталь о которой и знать особо не надо", но нередко бывает, что надо. С лайфтаймами и "одалживанием" ситуация ещё более явная — это надо знать и учитывать, если писать на Rust. Объявлять это базвордами — это примерно как такое же про плюсовые шаблоны. Это одна из штук на которых построен язык.


                Но вообще дело даже не в этом. Всякие там смарт-поинтеры, с одной стороны, не дают ничего принципиально нового — всё можно сделать и руками. С другой — мне без них весьма некомфортно, привык "полагаться на RAII". Так и с Rust: с одной стороны, "просто немного больше гарантий". С другой — разница настолько же принципиальная (а может и больше) как между ручной расстановкой delete/free и использованием RAII.


        1. LifeKILLED
          27.05.2016 13:27

          С вашей подачи меня тоже бомбануло изучить Rust и накидать на нём какой-нибудь графонистый 3д-двиг с шейдером и всем таким :) Это же классно — взять, изучить какой-нибудь новенький язык и что-нибудь на нём наваять :)

          Если честно, тарабарщина вроде «fn» вместо «function» (или его отсутствия, как в C/C++) меня раздражает, но если язык предрасполагает к осторожности и исключает многие ошибки, с которыми сталкиваешься в программировании на C/C++, стоит попробовать пописать на нём, хоотя бы чисто для души в свободное время :)


        1. guai
          27.05.2016 20:06
          -2

          с 'practical' у него как-то не ахти.


  1. dbagaev
    25.05.2016 18:46
    +9

    Многие вещи в С++ и во многих других языках были придуманы именно для удобства, а не для производительности, начиная с виртуальных функций. Так это даже не С++98! Хотите скорости и простоты? Используйте соответствующее подмножество языка, как делают многие разработчики игр и других высокоскоростных систем.

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

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


    1. Antervis
      31.05.2016 17:04

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


  1. Ramdeif
    25.05.2016 19:00
    -6

    Добавлю пару слов о производительности. C++ действительно все больше усложняется, появляются механизмы, упрощающие написание кода. Разумеется, иногда это приводит к потере скорости, т. к. чем удобнее и красивее код снаружи, тем он медленнее и меньше оптимизирован под конкретную задачу. Python, например, гораздо медленнее, чем C++, но на нем писать приятнее, проще и быстрее. Если же вам нужна хорошая производительность и не важна скорость и удобство разработки, берите чистый C или Assembler. C++ как раз является чем-то средним между ними.


    1. izvolov
      25.05.2016 20:27
      +6

      чем удобнее и красивее код снаружи, тем он медленнее и меньше оптимизирован под конкретную задачу

      Это ложное утверждение.
      См. STL.


      1. zed_0xff
        26.05.2016 14:07
        -1

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


        1. izvolov
          26.05.2016 14:38
          +1

          Даже если так, то в нормальной сторонней библиотеке эти классы, скорее всего, будут STL-совместимые.


  1. devpony
    25.05.2016 20:08
    +15

    Со временем C++ превратился из «быстрого» языка в «функциональный»

    imageimageimage


  1. sir_Maverick
    25.05.2016 22:16
    -1

    Три года изучения и практики коту под хвост, что же теперь делать?


  1. TarakanoLov
    25.05.2016 22:29

    Насчет сборки при небольших изменениях: чекни что идиому pimpl


    1. BarrelRoll
      26.05.2016 21:39

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


  1. VolkovAlexandr
    25.05.2016 22:30

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


    1. kemiisto
      25.05.2016 23:17
      +4

      Откровенно говоря, такие вот упоминания Fortran уже осточертели: fвтор просто демонстрирует своё незнание современного состояния этого языка. Был пару-тройку лет тому назад у небезызвестного в сообществе С++ Герба Саттера докладик (Not Your Father’s) C++. Так вот перефразируя Герба, всем писакам, которые упоминают Fortran в качестве примера этакого вымирающего «языка-динозавра», можно ответить: This is Not Your Grandfather’s Fortran! COBOL — вот да, мертвечина, выкатывающая только на «легаси», а на современном Fortran сейчас зачастую и новые проекты начинают. Бог мой, да в Fortran модули есть уже с начала 90-х, а кое-кто всё никак не разродиться. :D


      1. Kobalt_x
        26.05.2016 08:28
        +1

        На Фортране пишут для совместимости с уже написанным софтом. А вот взять какой-нибудь scalapack, blacs в котором f77, тот самый дедушуин фортран, отлаживать баги в котором боль. И самое печальное переписывать никто ничего не будет ибо священная корова обратной совместимости.


        1. kemiisto
          26.05.2016 11:59
          +2

          77 — это уже таки «папин», а «дедушкин» лучше и не видеть. :D Арифметический IF, цикл со счётчиком — числом с плавающей точкой, неявная типизация, Холлеритовские константы, отсутсвие стандарта и, как следствие, куча не совсем совместимых диалектов. Оно многое перкачевало и в «папин», и даже в современный, но уже минимум как deprecated. А в «дедушкином» это всё было в полный рост, так сказать. Тот FORTRAN (до 66 включительно) был создан, чтобы страдать. :D 77 — это уже было хоть что-то. По поводу всяческих LAPACK'ов: в этих пакетах сконцентрирован (пускай и не в лучшей форме) опыт численных расчётов целого поколения. Багов там, к слову, не так уж и много, а с нуля такое переписывать — это та ещё задача. А настоящая боль — это отлаживать (да что там отлаживать, хотя бы понять, где проблема и в чём она заключается) шаблонный код на С++. Если речь о «числодробилках», в качестве примера посмотрите на тот же Eigen.


    1. red_andr
      25.05.2016 23:50

      Присоединяюсь. По существу, Фортран никуда не делся, он как был языком для высокопроизводительных программ для численного моделирования и расчётов, так им и остался. Как он жил в этой нише, так и продолжает там жить, причём практически никого не впуская в своё логово, несмотря на взрывное развитие технологий и языков программирования. Если посмотреть какие задачи крутятся на суперкомпьютерах из Топ 500, то почти все они написаны на Фортране. Конечно, это совсем уже не тот Фортран, что работал на ламповых ЭВМ начала 50-х, но продолжает оставаться простым и эффективным языком.


  1. kemiisto
    25.05.2016 23:08
    -1

    Основной недостаток С++ не в том, что описано в статье. Проблема заключается в том, что изначально С++ был спроектирован, мягко скажем, так себе, а за годы из-за постоянных попыток что-то поправить при жестоких требованиях обратной совместимости разросся просто до монструозных масштабов. Сейчас вот глянул, стандарт С++14 (черновик N3797) — это 1366 страниц, С++17 запросто преодолеет 1500. Такой объём уже в принципе не осязаем одним конкретным человеческим индивидом, т.е. сейчас на планете вряд ли вообще существует человек, который знает весь С++. При этом ограничиться каким-то подмножеством на практике по сути не возможно: любая самая идиосинкразическая «фича» С++ рано или поздно просочиться через сторонние библиотеки. А эти библиотеки, зачастую, единственный аргумент в наше время писать на С++.


    1. Bas1l
      26.05.2016 00:50
      +4

      Нужно заметить, что начиная со страницы 411 идет описание стандартной библиотеки, а потом аппендикс. Так что стандарт для синтаксиса—410 страниц. Для сравнения: у C# образца 2006 года, например, и того больше—443 страницы до аппендиксов (классы .Net в документе не описываются, разумеется—это только Language specification).


      1. kemiisto
        26.05.2016 12:09

        Ну нет уж. Просто так отбросить часть про стандартную библиотеку нельзя. Там, зачастую, есть разделы, которые чисто формально относяться к стандартной библиотеке, а не к языку. Это особенно верно, если речь идёт о современном С++. Взять те же умные указатели. Чтобы писать на современном С++, необходимо их знать, что называется, «от и до», а описаны они в разделе про стандартную библиотеку. Так что, к 400 страницам про сам язык, 100 ещё спокойно можно накинуть про части стандартной библиотек без которых вообще никак. Ну хорошо, пускай будет не 1500, а 500. Это что-то меняет? Ничего. Утверждение, что С++ — монструозен и принципиально непознаваем остаётся верным. Почитайте любой тред про «будет/не будет UB», там всегда сначала такой спектр мнений, и это при том, что у всех есть текст стандарта под рукой. Просто на 500 страниц правил многовато вышло, сразу всего в голове не удержишь.


      1. kemiisto
        26.05.2016 12:17

        Так а C# то тут вообще причём? Такая же «помойка мыслей» как и С++. И что с того?


        1. DarkEld3r
          26.05.2016 13:21
          +2

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


        1. creker
          26.05.2016 14:01

          С того, что таки C# понимают и знают полностью куда больше людей. Это не настолько сложно, несмотря на вроде бы большой объем. С++ при схожем объеме выходит куда сложнее. Просто в C# не «помойка мыслей», а таки там над языком люди думали действительно, чтобы сделать его простым для понимания даже с таким объемом ключевых слов и концепций, что у него успешно получилось. Он банально куда более детерминирован. С++ это помойка из UB и просто неочевидного поведения, вот в чем его проблема, а не в объеме спецификации.


          1. kemiisto
            26.05.2016 14:32
            +4

            Моё мнение таково: утверждение, что C#, Java, любой другой монструозный язык куда проще С++ — это миф. Чуть проще за счёт несколько более вдумчивого проектирования (с учётом определённых ошибок С++), более узкой ниши и банально меньшего времени жизни. C# вот вдвое как младше С++, и судя по темпам раздувания, он ещё запросто и догонит, и перегонить последний.


            1. PsyHaSTe
              26.05.2016 18:55
              +1

              Не сказал бы, что как-то очень сильно раздувается. Хотя, конечно, некоторые фичи вроде оператора *is* мягко говоря смущают. Но в любом случае, еще лет 10 спокойной разработки на нем выжать можно, а там уже и смена подоспеет, типа того же Rust'а, только чуть более высокоуровневого. А то каждая программа на расте выглядит как будто я пишу на ассемблере — очень всё низкоуровнево. Хотя вроде конструкции достаточно абстрактные, язык по уровню выше С явно, но ограничения такие, что ощущение, что крылья к полу прибили. Хочется все то же, но не такой страшной ценой — и рыбку съесть, и все остальное короче. Думаю, за эти же 10 лет эту проблему так или иначе решат.


  1. OlegMax
    25.05.2016 23:20
    +8

    Перед чтением статьи хорошо бы ознакомиться с Areas of Expertise автора. Становится очевидно, что это просто эталонный консультант ртом.


  1. San66
    25.05.2016 23:25
    +3

    А зачем «Интернету вещей» высокие скорости обработки? Наверняка можно обойтись готовыми недорогими модулями.


    1. Shamov
      27.05.2016 23:16

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


  1. White__Owl
    26.05.2016 00:34
    -2

    А кто автор статьи?


  1. Antervis
    26.05.2016 07:29
    -3

    Могу оспорить каждую вторую строчку из перевода…


  1. Lauren
    26.05.2016 08:29
    -1

    Я ожидал прочитать статью о проблемах, которые привносит новый стандарт в мир с++ и какие он решает, а здесь такое.
    Главное проблема с++ — отсутствие стандартных библиотек. Попытки её решение через «шаблонные библиотеки» типа boost выглядит страшно, особенно для молодых программистов. Правда есть POSIX, но он немного не стой оперы, да и не везде реализован.


    1. mikntp
      26.05.2016 10:33
      +3

      Что не так с boost? С каких пор «шаблонные библиотеки» стали страшным решением?
      Молодые программисты, то есть джуниоры, вряд ли будут использовать boost в своих проектах, так как в таких проектах по большому счету нет задач, которые не решаются через std. Даже если и придется, есть документация и примеры.


  1. 0x131315
    26.05.2016 11:23
    +5

    Для автора весь мир сосредоточен в системах высокочастотного трейдинга.
    Именно в этом контексте можно понять про vhdl: системы, требующие подобных скоростей, не могут позволить себе выполняться на медленном центральном процессоре, и вынуждены переходить на железные алгоритмы. Подобное происходит везде — все специализированные модули, сопроцессоры, так или иначе, выкристаллизовываются в железе.

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

    Интеловский перепрограммируемый модуль — не более чем попытка запилить универсальный сопроцессор, но перепрограммировать его так и так будут через фреймворки и синтезаторы, как сейчас юзают gpu через opencl/cuda, редко кто, разве что ради экстремальной оптимизации, будет там возиться с vhdl.
    Тем более железные сопроцессоры все-равно лучше: производительнее и дешевле: gpu и asic никуда не уйдут.

    Что касается IoT — автор загнул.
    Да, что-то небольшое и низкоуровневое может быть запрограммировано на ассемблере или vhdl, но более высокие и сложные уровни так и так упираются в языки высокого уровня: попробуй дать пользователю в зубы вместо веб-конфигуратора с галочками и кнопочками скрипт vhdl.
    Неужто всем поголовно быть хардкорными железячниками, чтобы заюзать типичную умную розетку, купленную в ближайшей лавке? Дико же.
    Да и как на vhdl запилить что-то сложное, с медиапотоками, расписаниями, сетевыми сервисами и т.п? Точнее сколько лет это пилить? А если нужна гибкость? Вот и вот — так и так в среднем слое нужна операционка.

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

    Проблема автора — он все больше и больше уходит в железо, в низкий уровень. Поэтому и уперся в ограничения языка высокого уровня. Потому и не удивительно, что ему удобнее более низкоуровневые средства.
    На низких уровнях да, С++ неудобен, порождает сильно неоптимальный код, тупит. Показательно thedeemon.livejournal.com/49226.html Но это временно — лет через 20 может обзаведется эвристикой и поумнеет. Потенциал есть.
    Но это не значит, что 99% остальных людей, которые про высокочастотный трейдинг слышали только в новостях, а про ассемблер вообще не слышали, должны внезапно начать массово переезжать на vhdl или ассемблер.

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

    Будет смешно, если машины начнут программировать на С/С++, вместо того, чтобы придумать свой язык. А так и может случиться: зачем выдумывать что-то новое, если старое прекрасно подходит, и его можно расширять под свои нужды бесконечно?
    Си же до сих пор актуален, без плюсов, хотя по факту мало отличается от ассемблера. Его не вытеснил С++. Просто Си на своем месте: достаточно высоко, чтобы не возиться с неудобным ассемблером, и достаточно низко, чтобы работать с железом напрямую. Оптимум.
    Ну а выше С++ ничего уже нет — С++ бесконечно уходит в высь, каждый год расширяясь.
    В общем С/С++ — самодостаточная ветка языков.


    1. vlad72
      26.05.2016 23:22

      Вам бесконечно увеличивающаяся сложность языка не мешает? Ну тогда хоть о других подумали бы…

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


      1. Antervis
        30.05.2016 06:39

        Cи/С++ всегда имели множество более заточенных конкурентов. И живее всех живых


        1. vlad72
          30.05.2016 17:06

          Прошлое не обязательно экстраполируется на будущее.


  1. TrolomenJirnota
    26.05.2016 11:24
    +1

    >> кроме того, отсутствуют совсем уж базовые функции, например, простейшая процедура разбиения строк
    Плюсую, в 11 стандарте родили, наконец, std::to_string, но отсутствие до сих пор подобных примитивов очень огорчает и удивляет :)


    1. Shamov
      26.05.2016 14:30
      +1

      Разбиение строк в С++11 можно делать через std::regex_token_iterator. Если сделать для него простенькую функцию-обёртку, то будет не хуже, чем split() в Python'е. И даже лучше, поскольку эту обёртку можно сделать шаблоном от типа контейнера, в котором нужно разместить части строки.


      1. JIghtuse
        26.05.2016 16:37

        Вот proposal довольно эффективного решения http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3510.html
        Но без Ranges и string_view работать будет не очень.


        1. Shamov
          26.05.2016 17:52

          Очень любопытно. Концепция обобщённого Delimiter'а, который сам может находить себя в строке, просто покорила меня своей изящностью. Только её надо немного расширить таким образом, чтобы тот же самый Delimiter можно было применять для обратной операции join(). И ещё я не совсем понял объяснение насчёт rvalue-строк. Точнее, там вообще нет объяснения того, как именно возвращаемый range будет захватывать ownership над исходной строкой.


  1. Shamov
    26.05.2016 11:24
    +12

    На самом деле, настоящая проблема состоит не в том, что С++ плохо подходит для разработки в области высокочастотного трейдинга, а в том, что сам высокочастотный трейдинг плохо подходит для того, чтобы на него ориентироваться. Торговля на бирже с такими скоростями — это какая-то бессмыслица. Где-то читал любопытный факт. Раньше среднее время владения ликвидными акциями составляло порядка четырёх лет, а теперь оно составляет около 20 секунд. Т.е. раньше это была инвестиционная деятельность, а теперь это какая-то клоунада. И что же в таких обстоятельствах прогнозирует автор? Оказывается, торговля всё ещё происходит недостаточно быстро. И развитие будет продолжаться в сторону дальнейшего увеличения скоростей. А С++, типа, стоит на пути этого развития и сдерживает прогресс. Хочется задать автору один единственный вопрос: «Are you insane?»

    Хотя, конечно, понять его можно. Если вся его работа состоит в основном из ревью чужого кода, то вполне естественно, что ему хочется того, чтобы другие люди писали код попроще. Ему не хочется подолгу разбираться в хитроумных вариативных шаблонах, а хочется читать код так быстро, как будто это не код, а обычный текст. Каждый раз, когда ему подсовывают сложные шаблоны, его эффективность (как ревьюера) резко снижается. И это вгоняет его в уныние. К сожалению, если писать код настолько простой, что он сможет ревьюить его быстро, это резко снизит эффективность тех программистов, которые его пишут.


    1. vlad72
      26.05.2016 23:16
      -2

      > К сожалению, если писать код настолько простой, что он сможет ревьюить его быстро, это резко снизит эффективность тех программистов, которые его пишут.
      Я думаю, что автор это понимает и просто подчеркивает, что С++ создан для написания, а не для чтения (что есть минусом в больших проектах).


      1. Shamov
        27.05.2016 07:13
        +1

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


        1. vlad72
          27.05.2016 21:23
          -2

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


          1. Shamov
            27.05.2016 21:43
            +3

            Проблема в том, что он видит ТОЛЬКО вопрос поддержания кода. Процесс создания кода его не особо волнует. В противном случае он проявлял бы чуть больше уважения к труду людей, которые этот код создают. Я имею в виду его «правило одной минуты». Ишь ты! Если он за одну минуту не может понять код, то значит этот код неверен. За подобные идеи нужно приговаривать, например, к трём годам чтения boost'а… Чтобы дурь немного повыветрилась!


            1. vlad72
              29.05.2016 01:45
              -1

              Так множество «создание кода» — это подмножество «поддержание кода». Поэтому тот, кого волнует второе, автоматически волнует и первое.


              1. Shamov
                29.05.2016 08:49
                +1

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


                1. vlad72
                  29.05.2016 13:57
                  +1

                  А-а… ))


  1. forgotten
    26.05.2016 14:15

    TL;DR Пишите на C


  1. EndUser
    26.05.2016 14:19
    +3

    «Основной ошибкой программиста является выбор С++ в качестве языка программирования» /Александреску/
    «Не читайте Александреску» /Степанов/


  1. saboteur_kiev
    26.05.2016 15:28
    +3

    «в современном C++ одно небольшое изменение зачастую влечет за собой полную пересборку проекта, на что нередко уходит до десяти минут.»

    Проекты, с которыми я работал последние 10 лет, редко собирались полностью быстрее чем за 40 минут. А один так и 8 часов. что за 10 минут у него собраться-то могло?


    1. PsyHaSTe
      26.05.2016 19:00

      Читаю я такие комментарии, и чувствую всемирную боль С++ разработчиков…


    1. LifeKILLED
      26.05.2016 21:42

      >> редко собирались полностью быстрее чем за 40 минут

      Но НЕ-полностью-то они собирались, надеюсь, быстрее? В смысле, та 8-часовая программа же состояла из отдельных библиотек, а не была одним связанным монолитом, который каждый раз приходилось компилировать по 8 часов? И какой направленности были эти программы? Трудно даже представить такого монстра.


      1. saboteur_kiev
        27.05.2016 00:46

        8 часов — сборка операционной системы с нуля на рабочей машине разработчика (i7/16gb).
        Честно говоря, основная затрата — дисковые операции, около 100 гбайт требовалось места на диске для сборки.

        Но все равно, 10 минут — это очень небольшие проекты.


        1. LifeKILLED
          27.05.2016 02:03

          Тогда понятно.