Как стать автором
Обновить
IT-эволюция - шутка парадоксальная. Например, сначала на компьютерах моделировали нагрузку на АТС, затем программно управляли вызовами, а теперь телефония - это облачное решение, которое разворачивается за несколько минут и объединяет все корпоративные коммуникации. Кажется, между этими изменениями мало общего. На самом деле они стали возможными благодаря принципам программирования, заложенным полвека назад. И чтобы лучше увидеть эту связь, мы решили вспомнить историю С++ - одного из самых “взрослых” языков программирования. Он может быть и удобным инструментом разработки, и ночным кошмаром, и частью корпоративной истории. std::begin( )
Подробности — под катом
Всего голосов 72: ↑65 и ↓7 +58
Комментарии 185

Комментарии 185

Такими крестиками «на боку» вместо глаз обозначаются мёртвые люди. Но, учитывая, что она улыбается… я даже боюсь предположить, что с ней ))
он использует неудобные заголовочные файлы

И при этом они все еще удобнее чем то, что предлагают остальные языки. Намного удобнее глянуть в хедер и увидеть что это вообще за класс такой, какой у него интерфейс, какие приватные функции есть, члены класса и вот это вот все, чем пролистывать огроменный файл и раз в 50 строк видеть название функции, а в случае с каким-нибудь JS вообще никогда не быть уверенным какие же члены класса вообще есть, потому что объявляется все в рандомных местах и доступно везде. Можно конечно же упомянуть про такую прекрасную вещь как документация и пользоваться ею, когда надо найти или узнать нужный функционал. Но если бы хоть у половины того, с чем приходится возиться, была документация — жизнь была бы сильно прекраснее. Но тут вам не там и живем с чем живем.
С современными IDE, не нужно что-то там пролистывать, чтобы узнать, что у класса есть и что он может. В языках с динамической типизацией, конечно, с этим посложнее. Но статически типизированные языки, начиная от C# и Java, и заканчивая более молодыми — в хедерах не нуждаются от слова «совсем».
Совсем уже без своих игрушек не могут. Зачем перекладывать на инструмент то, что можно учесть в дизайне языка?
А зачем отказываться от удобных инструментов, если можно ими пользоваться и не создавать себе трудностей. Или это лишает вас чувства элитарности?
Потому что универсальный вариант, не зависящий от инструмента, банально лучше.
Но сейчас сложно представить ситуацию, что Вы, например, окажетесь на необитаемом острове со старой мобилкой и спутниковым интернетом, — и это будет единственная возможность зайти на сервер по ssh и исправить досадный баг, который уносит миллионы денег компании в секунду.

Нынче самые начинающие джуниоры имеют и дома и на работе машины, которые без проблем тянут весь этот ворох инструментов, присутсвующих в IDE и устанавливаемых дополнительно. Реалии таковы, что никто давно за редким исключением не пишет чисто код чисто буквами чисто в текстовом редакторе без подсветки.
Да, сейчас способ написания программ в Блокноте (и т.п.) считается допотопным. Я свои до сих пор пишу в kate под Linux (хотя подсветка в нём есть). Там же и tex-статьи.
Нет. Универсальное решение всегда проигрывает специализированному.
Да никто не призывает от них отказываться. Хорошая IDE — это хорошо. Но получается, что IDE в данном случае скрадывает недостаток языка.
Тут ниже начали обсуждать «проблемы современных IDE» и др., а это уход в сторону. Проблема не в IDE, проблема в языке программирования, который затруднительно читать без костылей и подпорок.
Я бы посмотрел как сейчас пишут на андроид или на C# без IDE.

Давайте не будем уходить в сторону от хороших инструментов, которые развивались вместе с языком.
IDE это, конечно, хорошо. Но получается, что IDE в данном случае исправляет косяк языка. А лучше бы этого косяка не было изначально. Язык всё же должен быть в разумной степени самодокументируемым.
С современными IDE, не нужно что-то там пролистывать, чтобы узнать, что у класса есть и что он может. В языках с динамической типизацией, конечно, с этим посложнее. Но статически типизированные языки, начиная от C# и Java, и заканчивая более молодыми — в хедерах не нуждаются от слова «совсем».
Да да, а потом смотришь код таких граждан в VCS и все ссылки и типы объявлены как var, конечно они даже и подумать не могут, что их г-но будут читать не из их любимой IDE, review тоже доставляет.
Код должен быть такой, чтобы его было читать удобно даже из блокнота, более того, не все компилят код из IDE всегда, иногда бывает так, что есть блокнот или vim.
Любая ide предложит вам посмотреть на структуру класса, на сколько бы тысяч строк его не растянули. А тот же хедер может быть засорен так что вам его придется часами разглядывать. Но ide вам и тут поможет.
НЛО прилетело и опубликовало эту надпись здесь
А какими IDE вы пользовались, если не секрет?
НЛО прилетело и опубликовало эту надпись здесь
У меня основной язык — C# и немного C++. От Visual Studio у меня сугубо положительные впечатления, особенно от последних версий.

А вот IDEA, Eclipse, даже Rider было пользоваться некомфортно из-за тормозов. VSCode — это вообще чудо на JS, поэтому о нормальной скорости работы на больших проектах речи и быть не может.

Самое же быстрое, чем я пользовался, был Sublime Text — только в нём я мог полноценно работать с XML-ками на десятки мегабайт.
Скажем так студия жрет ресурсов не мало, а Idea еще больше. Не у каждого комп/ноут с 10 ядрами и 32 Gb оперативки.
Мне студия показалась по скорости не лучше IDE от JetBrains.
Не стоит спешить обощать. В паскале, к примеру, не нужно проглядывать весь файл. Что идёт на экспорт из модуля, находится вверху в своём блоке, что не идёт, то в отдельном блоке.

Это работает только без шаблонов. А с шаблонами вся реализация, как правило, оказывается точно так же вперемешку с объявлениями.

Можно делать forward-declaration-ы, но тогда замучаешься искать реализацию.

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

Ровно до тех пор, пока вы не используете шаблоны и, как следствие, header-only библиотеки. Ковыряться в исходниках того же boost без докумментации — то ещё удовольствие.

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

Кажется, Вы путаете заголовочный файл и объявление класса.
В Модула-2, например, есть файл определения модуля и файл реализации. В файле определения есть всё, что вы любите в заголовочном файле, но в отличие от последнего, это не просто кусок текста, который препроцессор куда-то вставляет, а лексическая единица языка. В современных реализациях Паскаля определение и реализация модуля находятся в одном файле, но синтаксически разделены (interface/implementation), interface находится в начале файла и по-прежнему показывает всё, что модуль экспортирует: функции, объявления классов и др. Такой подход обеспечивает однозначность экспорта/импорта и сильно облегчает работу линкеру, поскольку после компилятора уже ясно, откуда что берётся.
А то, что вы ругаете («пролистывать огроменный файл и раз в 50 строк видеть название функции»), это, по-видимому, подход C# (кажется, и Java тоже). Мне он тоже не нравится.

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

P.S. Вообще, отсутствие полноценных модулей — один из немногих реально серьёзных недостатков C++, в остальном этот язык близок к идеалу.
В файле определения есть всё, что вы любите в заголовочном файле, но в отличие от последнего, это не просто кусок текста, который препроцессор куда-то вставляет, а лексическая единица язык

Вот именно этого дико не хватает в C++. Квадратичная зависимость сложности компиляции от количества файлов — довольно серьёзная проблема.


А то, что вы ругаете («пролистывать огроменный файл и раз в 50 строк видеть название функции»), это, по-видимому, подход C# (кажется, и Java тоже). Мне он тоже не нравится.

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

Вот именно этого дико не хватает в C++. Квадратичная зависимость сложности компиляции от количества файлов — довольно серьёзная проблема.

C++ modules ещё не стандартизованы, но уже поддерживаются основными компиляторами (clang, gcc, msvc)
Простой поддержки модулей мало. Надо, чтобы и все библиотеки были переписаны с использованием модулей. А здесь уже решает обратная совместимость и принцип «работает — не трогай».
Последний раз, когда я интересовался этим, для C++ были предложены два несовместимых механизма модулей: один в MSVC, другой, кажется, как раз в clang. И именно из-за этого разнобоя модули так и не вошли в C++17. Я не в курсе, к сожалению, с тех пор что-то изменилось к лучшему? Им удалось договориться об общем синтаксисе?
Ещё нет; так что и в C++20 они не войдут.
Но пользоваться ими это ведь не мешает?
Мне, например, как-то боязно. Вдруг придётся нелюбимый компилятор использовать…
Хотя я пользуюсь большей частью gcc (под виндой, соответственно, MinGW).
НЛО прилетело и опубликовало эту надпись здесь
В недрах Bell Labs Деннис Ритчи и Кен Томсон решают перенести созданную ими ОС UNIX, а заодно и любимую компьютерную игру на другой компьютер

В Советском Союзе тоже внедряли ОС UNIX под брендом МОС ЕС (Мобильная Операционная Система Единой Серии) как на менфреймах так и персоналках:



А если говорить про язык Си, то жутко вспомнить с каким боем в 80-е году приходилось его внедрять, пробиваясь через полчища любителей PL/1/

В своё время я долго объяснял программисту PL/1, почему индексация в массивах в Си начинается с нуля. Потом были полчища любителей Паскаля.

А потом


Как мы ждали Аду. И как потом плевались.
Паскаль — 30 синтаксических конструкций.
Ада — 180 синтаксических конструкций.
Все, что потребовал заказчик добавить в язык было именно добавлено. Списком, без малейшей попытки соблюдать заложенный Виртом «принцип ортогональности».
Картинки — Огонь!

Пользуетесь статическим анализом? Какими компиляторами собираете? Смотрите ли в сторону Rust

Пользуетесь ли статическими анализаторами? Какими компиляторами собираете? Смотрите ли в сторону Rust

Ох, уж эта мобильная версия.

Но почему нельзя писать «Си»? Просто «С» разве не путает?
К сожалению, автор статьи пишет неправильно — «С», и это, конечно, путает. Если писать правильно — «C», проблемы бы не было.
И как вы их различаете? Какая-то подсветка или шрифт другой?
Я робот, и читаю поток байт с сервера. Для меня это просто разные символы.
Обычно подчёркивание. У Меня Vim например подчёркивает в зависимости от языка спеллчекера текущего. Или только вторую «С» или всё кроме неё.
НЛО прилетело и опубликовало эту надпись здесь
Дата «когда будет опубликован C++20 как стандарт» и «С++20 принят как дефолтная версия стандарта в продакшене и весь код использует его фичи» могут различаться на долгие годы.
Я вот с одной стороны жду модули и концепты, но с другой стороны понимаю что не появятся они автоматически а) в версии используемых нами компиляторов (переход на новый MSVC допустим, не бесплатный) б) во всех основных используемых библиотеках (прикиньте весь Qt переписать на модули?) в) что все это добро будет совместимо с поддерживаемыми нами платформами (привет, поддержка XP и старых макосей).
Так что несколько лет еще придется «облизываться», так что «скоро» — кому как)
В том-то и дело, что скоро 20-й год, а будет ли на самом деле С++20 (и если будет, то в каком году) это ещё лишь гипотеза, а не факт.

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

После нескольких лет перерыва работы с C++, вернулся к нему вновь (по фин. соображениям в основном). Изменения (начиная с С++11), конечно, полезны и приятны. Но расстроило даже не то, что это всё происходит медленно и не во всех компиляторах реализуется синхронно, а то, что почти всё притащено из D (и, веротяно, откуда-то ещё). Т.е. концептуально С++ стал уже не флагманским, а догоняющим.
Флагманским он остаётся дефакто, из-за бизнес соображений, кучи кода, который надо поддерживать и развивать.

В этотм смысле подель разработки скажем, Python, мне как-то больше понятна. Есть PEP'ы, какие-то из них принимаются, есть план развития некий. Новая минорная версия сохраняет обратную совместивость, но не сохраняет прямую. Мажорная смело рушит обратную.
Всё идёт довольно планвно, можно планировать развитие проекта.
Что ожидать от C++ консорциума неизвесто.
Уверен некоторые вещи притащили из Rust, который лично мне смотрится проще и интереснее.
#КоментарийПроRust

переход на новый msvc (компилятор) бесплатен
вот переход на новую msvs (студию) — да, стоит денег


msvc сейчас лучше и быстрее всех внедряют новые фичи языка, буквально весной msvc полнее всех остальных компиляторов поддерживал c++17

msvc сейчас лучше и быстрее всех внедряют новые фичи языка, буквально весной msvc полнее всех остальных компиляторов поддерживал c++17

Какие Ваши доказательства? (С)
Т.е. ссылочку на подробное исследование хотелось бы посмотреть. Действительно ли там все компиляторы рассмотрены. К тому же, что такое «лучше» мне вообще не очень понятно, а вот «быстрее» это как раз действительно измеримо.

Вот, например, Сlang 5.0.1 (в OpenBSD 6.3) тоже вроде поддерживал «уже всё» из c++17 (как мне показалось) уже весной. Но утверждать решительно не берусь.

А с msvc есть контрпримеры из прошлых версий, когда тоже «вроде всё» уже поддерживалось. Например, компилятор из студии 2013 не поддерживает такую фичу С++11, как in-place инициализация массивов.

ну я судил по табличке поддержанных фич в компиляторах на cppreference


https://en.cppreference.com/w/cpp/compiler_support


там кстати до сих пор msvc лидер

ну лидер только в смысле «в первых трех местах» :D

Что я считаю важного MS сделала с последней версией — то что она сделала бинарную совместимость между двумя версиями компилятора. Это просто ключевой момент, на мой взгляд — разработчикам больше не нужно ждать, «когда же vendorname запилит поддержку нового VC», можно просто брать и использовать скомпиленную под 2015 библиотеку (да, в большинстве случаев оно и в новой версии собирается, но увы не всегда)
>ну лидер только в смысле «в первых трех местах» :D
Parallelism TS в GCC и Clang где?
Таблица нуждается в некоторых пояснениях.
Что там за значения в ячейках? Версия компилятора? Вроде да. Вот у MSVC стоят 19.0*, 19.10*, 19.14*… У ms бардак разведён в том, что есть версия вижуальника (которая раньше была по номеру, 5,6,8,9, потом по году, 2013, 2017...), версия компилятора, которая не совпадает с первой (2013=12.0, 2017=19.15), а ещё есть версия msvc, сейчас (у меня) =14.15.26726 (это при MSVC=2017, cl=19.15). Т.е. все это «хорошо» знают и сходу осознают реальность :).

Почему со звёдочкой у них всё?
Почему 3-е место это лидер (там ведь не по алфавиту упорядочено)?
Что касается С++2a, там вообще пока глухо…
>Почему со звёдочкой у них всё?
Потому что
" * — hover over the version number to see notes"
>Почему 3-е место это лидер (там ведь не по алфавиту упорядочено)?
Потому что актуальный сейчас стандарт C++17 и там по фичам только у MSVC все ячейки зеленые, C++2a ещё не вышел как стандарт его фичи смотреть бессмысленно

Чегой-то? Я вроде изучал этот вопрос, Build Tools нельзя использовать, если у тебя не куплена лицензия на VS (по крайней мере одна, не знаю точно нюансы, я не юрист). Т.е. для коммерческой компании вот так взять халявный компилятор нельзя.
Ну и да, в достаточно большой компании большинство разработчиков привыкли к VS, чтобы вот так взять и отказаться от самой популярной IDE под Windows и заставить их пересадить на QtC/что еще.

возможно вы правы


в нормальных компаниях разработчики сами вольны выбирать, какую IDE использовать, либо не использовать вовсе, а использовать хоть nano

Ну вот и не вижу противоречия:)
Допустим в компании 50 разработчиков под Win, и пусть половина из них не согласна расстаться с VS. Пусть сейчас они пользуются VS 2015. Предположим на секунду, что и вправду для использования Build Tools достаточно приобрести 1 лицензию на VS (в чем сомневаюсь, еще раз). Но все равно это означает что для перехода на новую версию компилятора где-то надо выложить деньга на 25 лицензий VS 2017) И даже если руководство в целом одобряет такие траты, нужно как-то доказать что они оправданы, пусть даже без чиселок с графиками и прочего ROI булшита)
Дело не в том что руководство запрещает что-то использовать, скорее наоборот в предоставлении этой самой свободы.

(и да, я даже не буду обсуждать вариант «а давайте только части разработчиков новую версию дадим», это еще хуже чем не обновлять ничего вовсе)
Если у компании дела идут настолько плохо, что она не может выделять по $45 в месяц на подписку на VS IDE за каждого пользователя, то работать в ней, наверное, не стоит.
Скорее всего какая-нибудь госструктура. Где легче купить что-нибудь дорогое и роскошное для руководства, чем какую-либо мелочь нужную для работы. Потому что и в том и в другом случае — сложный бюрократический головняк со множеством инстанций. И у руководства есть мотивация всё это преодолеть и «выбить» ради себя любимого. Но в случае когда «можно обойтись», стараются именно обойтись.
Если это госструктура, то велика вероятность, что проблем с лицензированием вообще нет по причине того, что эти госструктуры никто не будет проверять.

Нужна Visual Studio? Не вопрос, просто качаем бесплатную версию. Да и Windows зачастую тоже пиратская будет.
Во многих случаях программисту вообще выдают рабочее место с уже настроенным окружением (или дают docker-образ). Это выходит проще, чем потом мучиться с зоопарком IDE и компиляторов.
А бывает docker-образ для «Native UI» окружения?
Вольны то вольны…
Но мне на последних трех работах постоянно советуют освоить что-то кроме vim. :-)
msvc сейчас лучше и быстрее всех внедряют новые фичи языка, буквально весной msvc полнее всех остальных компиляторов поддерживал c++17

май 2017-ого года: выходит gcc 7 с полной поддержкой c++17
декабрь 2017-ого года: стандарт с++17 официально опубликован
май 2018-ого: выходит msvc 15.7 с полной поддержкой с++17
ноябрь 2018-ого: некий vladon утверждает, что msvc впереди планеты всей

актуальные сводные таблицы по поддержке стандартов компиляторами можете посмотреть здесь: gcc/clang. MSVC опять впереди планеты всей — у них эти таблички надо искать в записях в блоге, например этой.
А поддержки функций to_chars, from_chars из библиотеки C++17 до сих пор нигде нет. Может кто знает когда они появятся?
НЛО прилетело и опубликовало эту надпись здесь
в gcc8 есть. Реализация тормозит (везде) потому что в первом варианте получилась циклическая зависимость. Это как раз хороший пример почему перед попаданием в стандарт фича должна быть реализована хотя бы в одном компиляторе
>май 2017-ого года: выходит gcc 7 с полной поддержкой c++17
>в gcc8 есть.
Мда я думал полная поддержка это когда все положения стандарта и библиотеки реализованы
НЛО прилетело и опубликовало эту надпись здесь
Ага, в компиляторе они допустим есть, но попробуйте с ними собрать проект под CMake скажем, без лишних телодвижений) Я лично пока не вижу способов не хардкодить зависимости для каждого файла (плюс прощай распределённая сборка на N машин). Не все так просто (я сама дочь девопс инженера)

Дело не в том что это нельзя «пощупать». Дело в том что внедрить это в сколько-то значимых масштабах — боль.
НЛО прилетело и опубликовало эту надпись здесь
Ну чего вы придираетесь? Это мем. Можете вбить «Крымчанка, дочь офицера». Простите если нарушил принятый на хабре официальный стиль, но не стоило на этом делать акцент
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
так проблема то в основном у студии, это они обычно стандарт поддерживают в полной мере через несколько лет. В gcc/clang всё намного радужнее. Например, в gcc с++17 был реализован раньше, чем стандарт был опубликован.
Наоборот: это комитет по стандартизации принял в C++17 фичи, которые к моменту обсуждения уже были реализованы в gcc и clang.

As it looks like, C++ will focus on a model, where major features get implemented in the major compilers first, and then get standardized with the feedback from that experience.
насколько мне известно, в стандарт может попасть фича, реализованная в любом из компиляторов «большой тройки». Например, концепты появились только в gcc и вот они уже в черновике с++20. В любом случае, ваш аргумент скорее доказывает мою первоначальную позицию об отставании MSVC.
Я о другом: что это не «мейнтейнеры gcc такие шустрые, что реализовали новый стандарт ещё до его публикации», это «мейнтейнеры gcc такие шустрые, что пропихнули свои новые фичи в стандарт».
принцип принятия нововведений в стандарт с++ несколько отличается от «кто первым встал того и тапки». Например, модули уже очень давно реализованы в msvc в качестве расширения компилятора. Их реализация комитет не устроила, и модули еще не в стандарте. Конкурировали, например, реализации корутин. А вот концепты только в gcc, причем у них даже сейчас стандартная библиотека реализована через концептоподобные builtin'ы.
Уже есть F# — куда более продвинутый язык! даже мне, не программисту, стало понятно при показе в сравнении с С++. Разве нет?
НЛО прилетело и опубликовало эту надпись здесь
Так и тут была статья с его сравнением в отношении к C#
habr.com/post/428930
Я посмотрел да сравнил, там у автора примеры есть.
НЛО прилетело и опубликовало эту надпись здесь
> А зачем комбинировать несколько языков, если можно обойтись одним?
Действительно, зачем иметь дома отдельно нож, ножницы, пилочку и пинцет, если всё это можно заменить одним швейцарским?
Проекты, разрабатываемые по принципу «каждой задаче по своему инструменту» часто представляют собой мешанину из простых, но скрепленных гвоздями, соплями и честным словом кусков. И пплодятся таски типа «переписать вот это на плюсы». Уж лучше когда сразу почти всё на них и делать. По крайней мере, тогда продираясь через кучу неявных переходов в коде ты не рискуешь провалиться в какой-нибудь трижды обернутый легаси скрипт на перле.
Подобные рассуждения кажутся очень убедительными, пока кто-то не произносит «SQL» :)
«А давайте запросы к базе данных писать на плюсах.»
Поскольку большинство сложных продуктов состоят сейчас из различных клиентов, файл серверов, серверов данных и серверов приложений, работающих к тому-же на разных платформах, сложно представить себе единый инструмент под все задачи.
Каждый новый релиз стандарта нас кормят обещаниями вот еще немного чуть чуть и все будет прямо в стандарте. Тем временем все продолжают упариваться шаблонами.
Так шаблоны испокон веков в стандарте. Или я не понял, о чём ты…
Речь вроде как о том что вместо чистых и ясных концептов, до сих пор «code bloat» из кучи enable_if-ов в каждой первой библиотеке.
`if constexpr` же
Наш ответ Кренигану, или «Почему C++ не является мои любимым языком».

if (N=M) или, например, printf( something,...) с пропущенным амперсандом — это всё, что вам надо знать про синтаксис C++.

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

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

Когда начавший впадать в маразм (или наоборот, хотевший новых денег) Вирт сделал новую версию Паскаля, в которой вместо
if something then
begin
end;

надо было писать
IF Something THEN

ENDIF
ну или как там в Модуле-2 принято, всем было пофиг. Просто багландовцы добавили в Паскаль то, что в нем не хватало. Ну и далее по нарастающей, что в Delphi, что в других компиляторах. И ни у кого не возникает вопросов, что те или иные средства ущербны и опасны. Паскаль используют и не матерятся.

Что сделали за это время с C++? Попользовались, часть попользовавшихся пришла к выводу, что как-то хреново, ножи, вилки, пистолеты торчат, запилили Жабу. Жаба снова не то, запилили C#. Еще время прошло, пришли Гугл и сказали, что у них инструмента нет, будут делать свой C с запретом вызова функций без присваивания результата переменной и ограничениями на форматирование, так что каждая программа выглядит для меня так, что хочется оторвать руки по самую задницу. Какого...? 21-ый век на дворе программированию уже 60 лет, и оказывается, что за это время не создали инструментов серверное ПО писать?? Серьезно? А может просто последние лет 30-40 просто занимались ерундой и разборками о допустимости множественного наследования и т. п. туфты неочевидной целесообразности?

Это без упоминания 100500 {}-язычков рангом поменьше.

Я, конечно, всё понимаю, но если какая-то технология изначально правильная, то она развивается последовательно, а не так, что здесь мы одно выкинем, там другое, тут у нас еще какая-то надуманная проблема, заниматься этим можно до бесконечности.
if (N=M) или, например, printf( something,...) с пропущенным амперсандом — это всё, что вам надо знать про синтаксис C++.

Эм… Что вы хотели этим сказать?
Но, когда УГ делают дяди, способные разобраться во всем этом плюсовом ужасе, то возникают сомнения, а нужна ли вся эта сложность, если результат одинаковый.

Эм… знать язык != быть хорошим программистом. Да и знать синтаксис != уметь программировать на этом языке.
Что сделали за это время с C++?

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

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

Эм… С++ сохранил обратную совместимость это вообще одна из самых главных задач при выпуске нового стандарта.
Эм… Что вы хотели этим сказать?


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

Да и знать синтаксис != уметь программировать на этом языке.


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

Обновляют стандарт каждые 3 года, а что насчёт вашего паскаля? Последнее развитие это дельфи и всё?


Ну я не слежу за всеми реализациями от игрушечного Pascal ABC.NET, до FPC, или Smart Mobile Studio, но в Delphi я для себя выделяю языковые стандарты 7, 2005, 2009, и разные добавления меньших масштабов. При этом добавляется именно то, что нужно в практической работе. И за 30-40 лет можно уже довести систему до состояния, когда серьезные обновления ей не требуются.

Я сейчас переписываю одну ненавистную софтину с C++ на Delphi, как мне рассказывали, один алгоритм там программист делал полгода. И то не сказать, что хорошо вышло. Не расчет вращения галактики, регистрацию сигналов со станка. Если не самый тупой человек за полгода не мог найти нормального решения, может его и нет, и сама идея изначально была неверной?

И со своей стороны я тоже могу сказать, что у меня тут развитие идет, а эти мазохисты на плюсах, которые на C# до сих пор не сбежали, поди до сих пор собственные строковые классы пишут. ИМХО C++ сейчас держится исключительно за счет миллиардов вложенных в развитие компиляторов. На его месте мог бы быть даже Бейсик, в самых первобытных формах, если бы в оптимизацию генерируемого им кода, так вложились.

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

Полторы калеки используют?


Embarcadero насчитывает 3 млн. пользователей их продукта. Про FPC я вообще не в курсе. Но хоронить уже устали. Сомневаюсь, что хоть одна фирма будет выпускать продукт в течение 10 лет, если его никто не покупает.

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


В истории Delphi был слом с переходом на юникод, и это было для всех больно. Было еще введение адресации строк с 0 для мобильной разработки, но по умолчанию оно отключено, и старый код не страдает. Но только в Visual Studio можно открыть проект, который делался то ли в этой, то ли в пред. версии и получать кучу непонятных глюков. Может потом исправили, но я запомнил студию именно так.
То, что если синтаксис языка допускает превращение одной допустимой синтаксической конструкции в совершенно другую допустимую синтаксическую конструкцию возможно всего-лишь из-за одной опечатки, то язык не пригоден к практическому применению.

Не поверите, но это позволяет любой язык. x = a + b; x = a — b;
Правда?

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

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

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

А вы не думали что тот-же C# и другие языки часто попросту не подходят? Я занимаюсь графикой, так вот там балом правит С++.
Может потом исправили, но я запомнил студию именно так.

Интересно как давно? Лет 10 назад? И причём тут студия? Мы же говорим про языки а не про IDE.
Не поверите, но это позволяет любой язык. x = a + b; x = a — b;


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

Вы правда в это верите?


А почему бы мне в это не верить, раз это подтверждается практикой?

А вы не думали что тот-же C# и другие языки часто попросту не подходят? Я занимаюсь графикой, так вот там балом правит С++.


Поправка, там балом правит не C++, а его оптимизированные компиляторы, хотя как с этим на x64 уже вопрос. Были бы столь же оптимизированные компиляторы у Бейсика, вы бы писали на Бейсике. И вряд ли вы пишите на C++ Builder'е
Это не язык, а принятая запись мат. выражений. Не делайте вид, что вы не поняли о чем я, и что вы на эти гвозди не садитесь через раз.

А какая разница? Она же написана на языке который используете. В С++ если код нормально написан, тоже не так просто сделать ошибку.
А почему бы мне в это не верить, раз это подтверждается практикой?

Какой практикой? Все живые языки продолжают развиваться, а те что не развиваются, их почти не используют 3 миллиона используют дельфи, вы считаете это много?
Поправка, там балом правит не C++, а его оптимизированные компиляторы, хотя как с этим на x64 уже вопрос.

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


Попадания не в те кнопки от качества написания кода не зависят. Я, например, постоянно попадаю, но тут же получаю ошибку проверки синтаксиса. А так да, if (5==n), опытный программист на Си легко решает любые несуществующие в Паскале проблемы.

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


1) 3 Млн — это проданных копий, сколько сидит на пиратках, или Лазарусе вряд ли вообще кто-то считал. Много это или мало? На фоне остромодных языков, скорее мало, но в абсолютных числах достаточно, чтобы самоподдерживаться. Если предположить, что в России программист (т. е. реально пишет какой-то код) каждый сотый, то получится, что на всю страну всего 1.4 млн. прогеров и на плюсах, и на Жабе, и на 1С, и каких-нибудь языках для SCADA-систем и PLC…

2) А что принципиально нового добавилось не то, что в C++, а в ЯВУ вообще за последние лет 20, что серьезно подняло производительность программиста? Не однострочные примеры, как в массиве заменить все элементы на их квадраты, а что-то действительно полезное. Как один автор пишет в книжке 2015-го года: «When I speak to Delphi developers about anonymous methods, many are at least aware of their existence, but almost no one uses them.»

эм… нет, там правит с++ потому что в этой сфере все пишут на С++, да в основном из-за производительность


Замкнутый круг, все пишут на A, потому что все пишут на A. Аналогично с Фортраном на суперкомпьютерах.

>С++ устроен так, что позволяет достичь такой производительности

Хорошо, вопрос без капли сарказма, какие особенности C++ позволяют этого достичь? В сравнении с другими языками, генерирующими нативный код.
Хорошо, вопрос без капли сарказма, какие особенности C++ позволяют этого достичь? В сравнении с другими языками, генерирующими нативный код.
Помогает дизайн языка, нацеленный на производительность. Если сильно заморочиться, можно например на pascal писать в стиле C. Но это не идеоматично, в сам язык вся эта адресная арифметика и трюки с памятью пришли потом, и паскаль-программисты не задумаются, где уместнее string, а где pchar.

Простой пример — невозможно паскалевский class разместить на стеке, только в куче, или делай record.
А таки шо вы имеете против record? У вас в плюсах они ЕМНИП от объекта неотличимы. И ИМХО это логично, что есть ссылочные классы и есть структуры\объекты на стеке.
Я хочу TForm положить на стеке, и хочу нормальный RAII, чтобы не городить лестницы из try-finally в каждой второй функции.

В плане дизайна объектов Delphi ближе к C#, чем к С++, т.к. разделяет классы и структуры, а также допускает легковесное множественное наследование интерфейсов.


Я не считаю это недостатком: классам с виртуальными методами не место на стеке.


А вот отсутствие RAII — проблема.

В C++ тоже есть и классы и структуры.
В C++ это одно и то же.
классам с виртуальными методами не место на стеке.
Интересно, почему? Так можно сказать: «классам с приватными полями не место на стеке», или назвать любое другое ограничение.
Потому что их в дельфи нет, а если нет значит никому ненужно, и пофиг что это это повышает производительность.
Тогда почему, несмотря на высокую производительность C++, в суровом энтерпрайзе для критичного ко времени работы кода все равно пользуются Java, где даже структур нет?

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

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

Высокочастотный трейдинг — достаточно критичная к скорости задача?

Да и там по мимо явы активно используют и С и С++
Потому что это повышает риск выстрела в ногу.
Ну, расскажите, где больше шанс выстрела в ногу, тут:
var f: TForm;
begin
  f := MyForm.Create;
  try
    f.ShowModal;
  finally
    FreeAndNil(f);
  end;
end;

или тут
  MyForm f;
  f.ShowModal();

Речь о C++, где могут появиться интересные приколы, если сделать static_cast<> до базового класса по значению.


Вы же о том, что в Delphi нет внятного синтаксиса для конструкторов и деструкторов.

если сделать static_cast<> до базового класса по значению.

Эм… зачем?
приколы, если сделать static_cast<> до базового класса по значению
А, понятно, снова защита от опечаток. Не дадим создать сложный объект как значение, чтобы не было проблем с обращением с этим значением. Что-то похожее было в недавней статье, пример, что слишком сильные языковые средства могут привести к сложностям в использовании.
Попадания не в те кнопки от качества написания кода не зависят. Я, например, постоянно попадаю, но тут же получаю ошибку проверки синтаксиса. А так да, if (5==n), опытный программист на Си легко решает любые несуществующие в Паскале проблемы.

Понимаете проблема в том что я очень давно не кодил на дельфи и не помню его синтаксис точно, но подобные случаи, где не тот символ ведёт к ошибке, есть во всех языка (не считая специфичных, хотя я думаю даже в липсе можно допустить что-то подобное), В том же С# есть такие ошибки, в Питоне так там вообще ппц, ошибся в имени переменной так программа даже не чихнёт, про JS так вообще не стоит говорить как и про PHP. И это как-то не вяжется с вашим утверждением что эти языки не пригодны к использованию ведь их используют и поактивней чем дельфи.
А что принципиально нового добавилось не то, что в C++, а в ЯВУ вообще за последние лет 20, что серьезно подняло производительность программиста?

За яву не буду говорить потому что плохо её знаю (на ум приходят лямбды развечто). А в С++ добавили очень много, 11 стандарт просто невероятно поднял производительность программистов.
Как один автор пишет в книжке 2015-го года: «When I speak to Delphi developers about anonymous methods, many are at least aware of their existence, but almost no one uses them.»

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

Ды нет, пишут на С++ по вполне объективным причинам.
Хорошо, вопрос без капли сарказма, какие особенности C++ позволяют этого достичь? В сравнении с другими языками, генерирующими нативный код.

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


В Паскале нету, сразу вылетит ошибка синтаксиса. И регистронезависимость в этом плане тоже плюс, не напишешь V1 и v1, а потом ткнешь мимо шифта.

Питоне так там вообще ппц, ошибся в имени переменной так программа даже не чихнёт


А он с контекстным объявление переменных? Когда-то еще в инсте, препод рассказывал известную историю про do i=1.10 в проге на Фортране, воспринятое, как присваивание и стоившее миллиардов, буквально улетевших в космос.

Ну а я курсе на 4-ом согласился за N рублей сделать прогу на Бейсике (QBasic 5 ЕМНИП), благо я что-то со школ помнил (в инсте уже Паскаль и Си, Васика не было, и мое мнение о нем было как о некой безвредной игрушке...). Прогу-то я сделал, и даже числа правдоподобные выдавала (решение ур. теплопроводности), но в процессе очень больно сел на эту подлянку с новой переменной и очень долго искал ошибку в небольшой чисто учебной программе. С тех пор я языки, в которых переменные не надо объявлять, просто ненавижу.

За яву


Я имел в виду ЯВУ (язык выс. ур).

11 стандарт просто невероятно поднял производительность программистов


Мог бы спросить, но вряд ли вы мне на пальцах объясните, если какие-то моменты мне непонятны будут. Погуглю.

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


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

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

пишут на С++ по вполне объективным причинам.


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

Кстати, Вики утверждает, что в мире каждый год пишется 5 млр. строк нового кода на КоболЬДе. Х) Я даже не знаю, что более вероятно, то, что переписать\сконвертировать до сих пор не могут в силу объективных факторов. Или где-то в бункерах сидят бородатые гномы, прикованные к компьютерным столам и кодят. На КоболЬДе.

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


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

Ну и какая ошибка синтаксиса вылетит если поставить минус вместо плюса? Или a[1] вместо a[i]?

При написании диплома три месяца ловил ошибку на Фортране. Тестовый прогон — 500 точек. Расчет проходит за секунду. Рабочий прогон 20000 точек. Задача снята по истечению часа, ни одной точки не рассчитано.
А дело в опечатке, которую ни я, ни множество более опытных программистов не заметили: EPS=.1-E5 вместо EPS=.1E-5
В том же С# есть такие ошибки

За счёт более сильной типизации (в C# нет автоматического приведения типов к bool) описка чаще приводит к ошибке компиляции.

Были бы столь же оптимизированные компиляторы у Бейсика, вы бы писали на Бейсике
Дело в самой концепции языка C/C++ — не платить за то, чем не пользуешься. Например, хочешь — используй строки, а хочешь — указатели в память на цепочки символов. Хочешь — размещай в стеке, хочешь — в куче, а если надо, стандартным контейнерам дай свой аллокатор и управляй размещением, как оптимально для задачи.

Дело не сколько в оптимизирующем компиляторе, сколько в перекладывании на программиста массы микро-решений, влияющих на производительность, которые компилятор не может принять сам. Но в этом и сложность писать на C/C++.
Скажем в Delphi никто не запрещает использовать вместо классов в куче, структуры на стеке, или старый object, была даже такая библиотека сверхлегкая KOL на них. Я не понимаю, почему в совр. версиях Delphi ввели у структур методы, но не объединили их с object'ом. PChar, как и масса других строк доступен просто для совместимости с WinAPI. А что касается аллокации, то там она осуществляется методами, которые при желании можно перекрыть и разложить всё так, как душе угодно.
Скажем в Delphi никто не запрещает использовать вместо классов в куче
Есть множество чужих классов, из той же VCL, которые программист не может превратить в структуры. Да и со своими тоже не сможет, если уже куча кода использует их как классы.
что касается аллокации, то там она осуществляется методами, которые при желании можно перекрыть и разложить всё так, как душе угодно
Это в стандарте языка, или надо лезть в кишки реализации? Есть библиотеки типа FastMM, но они частично на ассемблере, и сильно связаны с RTL.
В смысл в стандарте? Есть TObject от которого наследуются все, и у него есть NewInstance.
FastMM ЕМНИП давно интегрирован в VCL.
Есть TObject от которого наследуются все, и у него есть NewInstance.
Это кривое решение, потому что смешивает логику объекта и логику его размещения. В C++, например, есть синтаксис new, который позволяет создать (выделить память) с помощью указанного аллокатора, и другой объект этого же класса — другим аллокатором, например, стандартным.

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

FastMM ЕМНИП давно интегрирован в VCL.
Если мне надо будет написать свой, но чтобы он выделял не только мои объекты с кастомным NewInstance, а строки, к примеру?
Тогда, видимо, так же как в плюсах извращаться с PChar, если по какой-то причине родной управляемый String вам не подходит. Как вариант использовать ShortString. На практике вам его 255 символов длины в 99.9% случае за глаза хватит.

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

А разве структуры могут иметь наследование и методы?
Методы структурам завезли еще в Delphi 2005. И где-то я уже возмущался, что теперь есть классы в куче, есть старые object's еще из TP у которых и методы, и наследование, и структуры, у которых методы. Х)
Да но наследования то нет, я правильно понимаю?
Нету. Как и конструктора. А у object'а есть. Но здесь вопрос не только в странности ситуации, а еще и в том, как часто нужно наследование. Т. е. класс какого-нибудь интерфейсного элемента, наследуемый через 10 поколений это понятно и нормально, но, допустим юнит в стратежке можно спокойно описать структурой и работать с ним не как с некой цельной сущностью, как, например, с классом соединения с базой данных, а как с данными.

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

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

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

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


Если вы хотите именно ООП, то, конечно, печаль-беда, но ООП хорошо работает, когда у вас есть библиотека, да еще предполагающая расширение. Но если вам нужно описать 2-3, ну пусть даже 5 частных случаев, и код является конечным, то проблемка сильно меркнет.

BTW Я тут новости по след версии Delphi глянул, обещают конструкторы, конструкторы копирования для структур завезти. Ну прикольно, только до сих пор не завезли, походу, из-за управляемого String. Так что всех этих сишных геморроев просто не было. Точнее, его было сильно меньше.

А переменные всё ещё нужно писать в начале функции? (потихоньку стал вспоминать дельфи) А ректы могут быть дженериками?


Что за ректы? Рекорды? Ну можно сделать дженерик с ограничением, что это именно класс, рекорд, или интерфейс.

Объявление только в начале. Сейчас есть диалекты Паскаля, где навводили объявление в любом месте, но у меня подобное вызывает желание оторвать руки по самую задницу. В Pascal. ABC.NET есть присваивание в стиле a+=b; Может в Smart Mobile Studio есть. В принципе, в Паскале такая штука, в отличие от Си безопасна, т. к. a=b, если плюсик не нажал, сразу даст ошибку компиляции, но у меня подобное оптимизма не вызывает.

Да нет, просто в дельфях это костыль.


Ну Object еще в Turbo Pascal 5.5 появился.

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


Ну я вроде писал уже, я вижу 2 вещи:

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

2) Структуры\объекты на стеке, которые передаются по значению и действительно копируются, и всегда инициализированы сразу. В принципе, я уже и забыл, как там под новый record память выделять. Просто локально объявляю, и если нужно как-то дальше использовать, то в TList;
«Хочешь — размещай в стеке, хочешь — в куче»
А потом 80% уязвимостей связано с переполнением буфера, размещенного в стеке. Потому, что так «эффективнее».
Проблема не в размещении на стеке, а в отсутствии проверки границ буфера при записи. Сейчас очень много эксплуатируют переполнение буферов в куче. Для изменения потока выполнения вместо перезаписи адреса возврата перезаписывают адрес таблицы виртуальных методов у объектов в куче.
Если в буфер идет внешний поток данных, проверка переполнения необходимо перед каждым блоком. Во многих случаях перед каждым символом. В куче можно ограничиться прерыванием по нарушению границы.
Если уж размещать для ускорения буфер в стеке, то от проверки придется отказаться.
В общем так: опасная работа с буфером быстрее в стеке, а безопасная в куче.
Я не понимаю, почему. Например, у меня есть функция, которая читает данные в буфер (типичный recv(socket, ...) или ReadFile(hFile, ...)). В качестве параметров она принимает адрес буфера и его размер. Есть какая-то разница, передаю я ей буфер из кучи или со стека?
И что она с размером делает если, например, получает входящую информацию побайтно?
После каждого полученного и записанного байта подсчитывает оставшееся в буфере место.
Вот на этой проверке и экономят.
В куче возможно создать прерывание по выходу за пределы выделенной памяти. Сложно, но тогда проверять на каждом шаге есть ли еше место не требуется. Достаточно обработать прерывание в случае недостатка места в буфере.
В куче возможно создать прерывание по выходу за пределы выделенной памяти
Каким образом? Можете привести пример кода?
И что она с размером делает если, например, получает входящую информацию побайтно? После каждого полученного и записанного байта подсчитывает оставшееся в буфере место.

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


Вот на этой проверке и экономят.

Ошибки переполнения буфера возникают из-за того, что либо неправильно вычисляется сам размер буфера, либо используются функции, которые вообще не имеют такого параметра, как размер буфера (например, strcat).


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

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


Вы, конечно, можете написать свой менеджер динамической памяти, который для каждого выделяемого объекта будет вызвать VirtualAlloc/VirtualProtect/mprotect/что-то там ещё. Вот только это будет просто нереальным расточительством ресурсов. В этом случае гораздо эффективнее будет вместо C/C++ использовать более медленные языки, но без возможности выстрела в ногу.

Вы, конечно, можете написать свой менеджер динамической памяти, который для каждого выделяемого объекта будет вызвать VirtualAlloc/VirtualProtect/mprotect/что-то там ещё
Нет, не можете.
Например, если код, не проверяющий выход за пределы буфера написан так:
void* pixelArray = (char*)bitmapHeader + bitmapHeader->offsetToPixelArray;
memcpy(result, pixelArray, bitmapHeader->fileSize - sizeof(BITMAPHEADER));

То остаётся возможность чтения любого региона памяти, подсовывая в поле offsetToPixelArray некоторое значение, которое укажет на другую выделенную область.
только в Visual Studio можно открыть проект, который делался то ли в этой, то ли в пред. версии и получать кучу непонятных глюков
Справедливости ради, гораздо сложнее портировать проект с Delphi 7 на следующую Delphi XE. Особенно в большом проекте, где куча компонент, которые были нужны в своё время, но сейчас не поддерживаются. C++ лучше совместим с предыдущими вериями языка, свежий компилятор вполне собирает код 20-летней давности, разве что формат проекта мог поменяться, а языковые конструкции совместимы.
Ну это в основном следствие перехода на юникод. Как правило, можно втупую починить просто заменив String на ANSIString.

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

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

При этом работаем мы все-таки не с абстрактным языком, а с конкретным инструментом. И совершенно безотносительно языка мы можем использовать библиотеку 10-тилетней давности, которая перестанет нормально работать с очередной обновой ОС.
Реально проблемы только с портирования совсем древнего Паскалевского кода, где много ассемблера и вызовов функций Windows. Обычно этот код — калька с сишного. Просто потому, что в Windows и Unix были готовые библиотеки и заголовки для Си, а разработчикам на Паскале приходилось все адаптировать. Delphi 7 уже был спроектирован под реальную кроссплатформенность Windows/Linux. А в FreePascal/Lazarus кроссплатформенность довели до совершенства — write once, compile anywhere.
На словах всё красиво, но в реальных проектах есть FastReport 2.5 (с исходниками), поддерживающий Delphi 3-7 и более новые версии FastReport, поддерживающие D7, XE. Форматы шаблонов отчётов бинарно не совместимы. И никто в интернете не смог скомпилять старый FR в новой Delphi XE, а кто у нас пробовал, сказал — да я лучше 200 отчётов переделаю в новый формат )))
У меня FR 2.3 (свежее не нашел), и там для совместимости с новыми версиями достаточно в файле FR.INC отключить поддержку InterBase и ADO и включить режим Delphi10.
Это где вы взяли? Версия 2.52 датирована 2003 годом и никакой Delphi10 не знает.

Вот так там начинается fr.inc:

{******************************************}
{                                          }
{            FastReport v2.5               }
{              Include file                }
{                                          }
{Copyright(c) 1998-2003 by FastReports Inc.}
{                                          }
{******************************************}
Взял на официальном сайте — www.fast-report.com/en/product/free-report-vcl
А где можно глянуть вашу версию? Сходу найти не получается. Попробую ее сконвертировать под Delphi 10.2 и Lazarus, у меня в этом есть опыт.
Спасибо. Почему-то я проходил всегда мимо этого продукта (видимо, из-за переименования FastReport во FreeReport). Попробую его завести на XE. Отправил в ЛС ссылку на старую версию, просто если интересно. Ковырять это старьё не имеет смысла, из-за обновления, на которое вы дали ссылку.
Похоже, я жестоко ошибся в версиях, Delphi10 это на самом деле Delphi 2007, в которой еще даже уникода нет. Для современной Delphi 10.2 потребовались ощутимые доработки, поскольку огромное количество кода предназначено для поддержки совместимости с Delphi 2, где некоторых привычных функций и контролов еще не было. Например, TToolBar и TToolButton определены заново. А еще оно рассчитано на установку из бинарников, а не из исходников.
Нашел два готовых варианта адаптации под Delphi XE:
github.com/VencejoSoftware/FreeReport
github.com/jciberta/FreeReport
Спасибо. Главное тут понять, продукт теперь называется FreeReport
А Вы в курсе, что разработка Windows начиналась на паскале (см. макро PASCAL, что повсюду в Win16 SDK). И только набив шишки одумались и перешли на C.
Годный вброс )))

На самом деле, Паскалевская передача аргументов позволяет генерировать код короче, но не поддерживает функции с переменным числом аргументов (как требует, например, printf). Поэтому этот способ передачи параметров был способом оптимизации в старых компиляторах си.

Сейчас PASCAL переименован в __stdcall и в этом виде до сих пор здравствует.
Вызов C-шной функции с переменным числом параметров из Pascal-кода.
Ой, ассемблер, да и аргументы надо заворачивать в массив.
Вот решение куда короче и надёжнее, хоть и требует для каждой комбинации аргументов отдельную строчку в импорте.
function sprintf1(dst, fmt: pchar; a1: integer): integer; cdecl; external 'msvcrt.dll' name 'sprintf';

function sprintf2(dst, fmt: pchar; a1, a2: integer): integer; cdecl; external 'msvcrt.dll' name 'sprintf';

function sprintf3(dst, fmt: pchar; a1, a2, a3: integer): integer; cdecl; external 'msvcrt.dll' name 'sprintf';

function sscanf1(src, fmt: pchar; var p1: integer): integer; cdecl; external 'msvcrt.dll' name 'sscanf';

function sscanf2(src, fmt: pchar; var p1, p2: integer): integer; cdecl; external 'msvcrt.dll' name 'sscanf';

...

Вот так еще лучше :-)


function sprintf(dst, fmt: pchar): integer; cdecl; varargs; external 'msvcrt.dll';
Вброс? Хм… Вообще-то в Win16 API паскалевские соглашения по вызовам появились по конкретной исторической причине. И возможность вызова с переменным числом аргументов тут не главное отличие от cdecl, вообще-то. Просто изменить соглашения о вызовах в C компиляторе — не проблема, и при переходе на C решили не переписывать массу ассемблерного кода.
А stdcall — не pascal, и в Delphi используется другие соглашения. Так что не вброс.
Тогда приведите пруфы, что разработка Windows начиналась на паскале
Трудно искать ссылки 30-летней давности)))
Вот цитата из википедии:
Similarly, the internal implementation of the API's function has been developed in several languages, historically. Both the languages Pascal and x86 assembly had been heavily used in earlier versions of the Windows API, before C became dominant. A reminiscence of this is that the API functions still use the Pascal calling convention to restore the stack from pushed parameters after a call (although they expect parameters pushed from right to left, as most C compilers do, by default).
Это значит, что разработчики SDK предоставляли API в виде файла Windows.pas для удобного использования из Паскаля, но никак не тянет на утверждение, что разработка Windows начиналась на паскале.
Вы бы не могли подробно изложить рассуждения, приведшие Вас к такому выводу?
Both the languages Pascal and x86 assembly had been heavily used in earlier versions of the Windows API
«API», т.е. интерфейсная часть, не реализация.
В поставке Delphi есть, надо?
Скрытый текст
{*******************************************************}
{                                                       }
{       Borland Delphi Run-time Library                 }
{       Win32 API Interface Unit                        }
{                                                       }
{       Copyright (c) 1985-1999, Microsoft Corporation  }
{                                                       }
{       Translator: Borland Software Corporation        }
{                                                       }
{*******************************************************}
Вы чудо! Ну серьезно, заголовок файла Borland Delphi Run-time Library от 1985 года, безусловно, доказывает, что майкрософт до 1983 использовал паскаль только для описания интерфейсов. Смешно.
Еще раз: разработку Windows начали на паскале и ассемблере. А когда уперлись в непригодность паскаля для системного программирования, то перешли на C. И чтобы не переписывать ассемблерный код, для функций Win16 API использовали соглашения о вызовах pascal. Что и видно в заголовках Win16 SDK.
На этом дискуссию полагаю завершенной.
C++ лучше совместим с предыдущими вериями языка, свежий компилятор вполне собирает код 20-летней давности, разве что формат проекта мог поменяться, а языковые конструкции совместимы

Увы, у меня при сборке не 20-летнего, как вы пишете, а 10-летнего кода — обнаружились сдохшие библиотеки, а с новыми их версиями — тоже не всё гладко. :(
Эм… Что вы хотели этим сказать?

Проблема С++ в том, что он очень легко позволяет выстрелить себе в ногу благодаря не очень удачному дизайну языковых конструкций. Даже продвинутая IDE не всегда может помочь. Тот же блог PVS Studio показывает, что банальные описки могут висеть в реальном коде годами.


Эм… С++ сохранил обратную совместимость это вообще одна из самых главных задач при выпуске нового стандарта.

Совместимость не 100%, есть некоторые нюансы даже в самом языке. Кстати, именно из-за них при компиляции требуется явно указывать ключ (--std=c++11).


C++ лучше совместим с предыдущими вериями языка, свежий компилятор вполне собирает код 20-летней давности, разве что формат проекта мог поменяться, а языковые конструкции совместимы.

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


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


P.S. В плане лидеров обратной совместимости я бы поставил Java и C#, но уж никак не C++.

блог PVS Studio показывает, что банальные описки могут висеть в реальном коде годами.
Их любимая ошибка — «Эффект последней строки». Когда какую-то строку накопипастили и везде исправили, как надо, кроме последнего места. Но от языка это не зависит.
Их любимая ошибка — «Эффект последней строки». Когда какую-то строку накопипастили и везде исправили, как надо, кроме последнего места. Но от языка это не зависит.

Да, эффект последней строки от языка не зависит.
Зато if (a = b) и всякие косяки со скобками {} — вполне себе зависит.

Чем косяки со скобками отличаются от косяков с begin-end, или вы за Питоновские отступы?

Аккуратно пользоваться операторами надо везде. В SQL, например, нельзя писать where ORDER_DATE=null, в js надо различать =, == и ===. В принципе, это такой же нарабатываемый практикой навык, как различать арифметические операторы + и -. Только эти учат со школы, а те операторы позже. Кто давно программирует, имеет с присваиванием проблем не больше, чем с + / -.

Кто давно программирует, имеет с присваиванием проблем не больше, чем с + / -.

Проблема не с присваиванием, а с банальными опечатками.

Здесь всё очень индивидуально.
Кому-то нравится писать длинные слова, типа procedure и function, есть время подумать, пока печатаешь. Кому-то нравится эзотерический набор знаков пунктуации, по типу Perl или Forth.

В C++ для меня хороший баланс. Я не готов жертвовать конструкциями типа
while (*src++ = *dst++);
ради защиты от опечаток, я не хочу это превращать в
while src^ do
begin
  src^ = dst^;
  inc(src);
  inc(dst);
end;
dst^ = 0;
Кому-то нравится писать длинные слова, типа procedure и function, есть время подумать, пока печатаешь.

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


В C++ для меня хороший баланс. Я не готов жертвовать конструкциями типа ...

Вот за такое:
while (*src++ = *dst++);
ругать надо.


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


Я бы написал:


do
{
    *src++ = *dst++;
}
while (*dst);

либо вообще
strcpy(dst, src);


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

Я бы написал:
do
{
*src++ = *dst++;
}
while (*dst);
И тоже с ошибкой )))
Например, для char dst[10] = "\0********";
Modula 2, по моему мнению, была прекрасна, а все, что делал Borland в целом и Ф. Кан в частности с 1990-какого-то года вызывает у меня желание кинуть гранату. ЕМ и что же? Субъективненько как-то
Ага, в Паскале оно называется unit, а в «Модуле», внезапно Module. X) А в плюсах, вроде, до сих пор ничего подобного не появилось.

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

Но в нормальных модулях есть еще и настройка доступа, а так же инициализация и финализация. Что делает их похожими на классы…
Тем, что в C++ заголовочный файл не является самостоятельной единицей трансляции, а разделение на cpp и h — это простая условность.
Или оттенки и степени прилагательных. «Хороший» — для кого хороший? А «плюсовой» исключает субъективность. Опять же, если вам нужно что-то сильнее «плюсового», какой смысл иметь целый набор расплывчатых бесполезных слов — «великолепный», «отличный» и так далее? «Плюс плюсовой» охватывает те же значения, а если нужно ещё сильнее — «плюсплюс плюсовой». Конечно, мы и сейчас уже пользуемся этими формами, но в окончательном варианте новояза других просто не останется. В итоге все понятия плохого и хорошего будут описываться только шестью словами, а по сути, двумя.
Оруэлл. 1984
Зарегистрируйтесь на Хабре , чтобы оставить комментарий