Комментарии 185
он использует неудобные заголовочные файлы
И при этом они все еще удобнее чем то, что предлагают остальные языки. Намного удобнее глянуть в хедер и увидеть что это вообще за класс такой, какой у него интерфейс, какие приватные функции есть, члены класса и вот это вот все, чем пролистывать огроменный файл и раз в 50 строк видеть название функции, а в случае с каким-нибудь JS вообще никогда не быть уверенным какие же члены класса вообще есть, потому что объявляется все в рандомных местах и доступно везде. Можно конечно же упомянуть про такую прекрасную вещь как документация и пользоваться ею, когда надо найти или узнать нужный функционал. Но если бы хоть у половины того, с чем приходится возиться, была документация — жизнь была бы сильно прекраснее. Но тут вам не там и живем с чем живем.
Нынче самые начинающие джуниоры имеют и дома и на работе машины, которые без проблем тянут весь этот ворох инструментов, присутсвующих в IDE и устанавливаемых дополнительно. Реалии таковы, что никто давно
Тут ниже начали обсуждать «проблемы современных IDE» и др., а это уход в сторону. Проблема не в IDE, проблема в языке программирования, который затруднительно читать без костылей и подпорок.
С современными IDE, не нужно что-то там пролистывать, чтобы узнать, что у класса есть и что он может. В языках с динамической типизацией, конечно, с этим посложнее. Но статически типизированные языки, начиная от C# и Java, и заканчивая более молодыми — в хедерах не нуждаются от слова «совсем».Да да, а потом смотришь код таких граждан в VCS и все ссылки и типы объявлены как var, конечно они даже и подумать не могут, что их г-но будут читать не из их любимой IDE, review тоже доставляет.
Код должен быть такой, чтобы его было читать удобно даже из блокнота, более того, не все компилят код из IDE всегда, иногда бывает так, что есть блокнот или vim.
А вот IDEA, Eclipse, даже Rider было пользоваться некомфортно из-за тормозов. VSCode — это вообще чудо на JS, поэтому о нормальной скорости работы на больших проектах речи и быть не может.
Самое же быстрое, чем я пользовался, был Sublime Text — только в нём я мог полноценно работать с XML-ками на десятки мегабайт.
Это работает только без шаблонов. А с шаблонами вся реализация, как правило, оказывается точно так же вперемешку с объявлениями.
Намного удобнее глянуть в хедер и увидеть что это вообще за класс такой, какой у него интерфейс, какие приватные функции есть, члены класса и вот это вот все
Ровно до тех пор, пока вы не используете шаблоны и, как следствие, header-only библиотеки. Ковыряться в исходниках того же boost без докумментации — то ещё удовольствие.
Кажется, Вы путаете заголовочный файл и объявление класса.
В Модула-2, например, есть файл определения модуля и файл реализации. В файле определения есть всё, что вы любите в заголовочном файле, но в отличие от последнего, это не просто кусок текста, который препроцессор куда-то вставляет, а лексическая единица языка. В современных реализациях Паскаля определение и реализация модуля находятся в одном файле, но синтаксически разделены (interface/implementation), interface находится в начале файла и по-прежнему показывает всё, что модуль экспортирует: функции, объявления классов и др. Такой подход обеспечивает однозначность экспорта/импорта и сильно облегчает работу линкеру, поскольку после компилятора уже ясно, откуда что берётся.
А то, что вы ругаете («пролистывать огроменный файл и раз в 50 строк видеть название функции»), это, по-видимому, подход C# (кажется, и Java тоже). Мне он тоже не нравится.
Я это к тому, что переход от заголовочных файлов к модулям — это не обязательно переход к бардачному стилю C#, есть и более удачные, хоть и менее популярные решения.
P.S. Вообще, отсутствие полноценных модулей — один из немногих реально серьёзных недостатков C++, в остальном этот язык близок к идеалу.
В файле определения есть всё, что вы любите в заголовочном файле, но в отличие от последнего, это не просто кусок текста, который препроцессор куда-то вставляет, а лексическая единица язык
Вот именно этого дико не хватает в C++. Квадратичная зависимость сложности компиляции от количества файлов — довольно серьёзная проблема.
А то, что вы ругаете («пролистывать огроменный файл и раз в 50 строк видеть название функции»), это, по-видимому, подход C# (кажется, и Java тоже). Мне он тоже не нравится.
Если писать код в соответствии с принципами SOLID, то вы просто выделяете всё это в интерфейсы, и никакой необходимости шерстить их реализацию в этом случае попросту нет.
Вот именно этого дико не хватает в C++. Квадратичная зависимость сложности компиляции от количества файлов — довольно серьёзная проблема.
C++ modules ещё не стандартизованы, но уже поддерживаются основными компиляторами (clang, gcc, msvc)
В недрах Bell Labs Деннис Ритчи и Кен Томсон решают перенести созданную ими ОС UNIX, а заодно и любимую компьютерную игру на другой компьютер
В Советском Союзе тоже внедряли ОС UNIX под брендом МОС ЕС (Мобильная Операционная Система Единой Серии) как на менфреймах так и персоналках:
А если говорить про язык Си, то жутко вспомнить с каким боем в 80-е году приходилось его внедрять, пробиваясь через полчища любителей PL/1/
Пользуетесь статическим анализом? Какими компиляторами собираете? Смотрите ли в сторону Rust
Пользуетесь ли статическими анализаторами? Какими компиляторами собираете? Смотрите ли в сторону Rust
Я вот с одной стороны жду модули и концепты, но с другой стороны понимаю что не появятся они автоматически а) в версии используемых нами компиляторов (переход на новый MSVC допустим, не бесплатный) б) во всех основных используемых библиотеках (прикиньте весь Qt переписать на модули?) в) что все это добро будет совместимо с поддерживаемыми нами платформами (привет, поддержка XP и старых макосей).
Так что несколько лет еще придется «облизываться», так что «скоро» — кому как)
Бремя обратной совместимости, эпизоотия разнородных компиляторов — это наверное основные, но все факторы, способствущие очень медленному развитию.
После нескольких лет перерыва работы с C++, вернулся к нему вновь (по фин. соображениям в основном). Изменения (начиная с С++11), конечно, полезны и приятны. Но расстроило даже не то, что это всё происходит медленно и не во всех компиляторах реализуется синхронно, а то, что почти всё притащено из D (и, веротяно, откуда-то ещё). Т.е. концептуально С++ стал уже не флагманским, а догоняющим.
Флагманским он остаётся дефакто, из-за бизнес соображений, кучи кода, который надо поддерживать и развивать.
В этотм смысле подель разработки скажем, Python, мне как-то больше понятна. Есть PEP'ы, какие-то из них принимаются, есть план развития некий. Новая минорная версия сохраняет обратную совместивость, но не сохраняет прямую. Мажорная смело рушит обратную.
Всё идёт довольно планвно, можно планировать развитие проекта.
Что ожидать от C++ консорциума неизвесто.
переход на новый 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 лидер
Что я считаю важного MS сделала с последней версией — то что она сделала бинарную совместимость между двумя версиями компилятора. Это просто ключевой момент, на мой взгляд — разработчикам больше не нужно ждать, «когда же vendorname запилит поддержку нового VC», можно просто брать и использовать скомпиленную под 2015 библиотеку (да, в большинстве случаев оно и в новой версии собирается, но увы не всегда)
Что там за значения в ячейках? Версия компилятора? Вроде да. Вот у 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 ещё не вышел как стандарт его фичи смотреть бессмысленно
Ну и да, в достаточно большой компании большинство разработчиков привыкли к VS, чтобы вот так взять и отказаться от самой популярной IDE под Windows и заставить их пересадить на QtC/что еще.
возможно вы правы
в нормальных компаниях разработчики сами вольны выбирать, какую IDE использовать, либо не использовать вовсе, а использовать хоть nano
Допустим в компании 50 разработчиков под Win, и пусть половина из них не согласна расстаться с VS. Пусть сейчас они пользуются VS 2015. Предположим на секунду, что и вправду для использования Build Tools достаточно приобрести 1 лицензию на VS (в чем сомневаюсь, еще раз). Но все равно это означает что для перехода на новую версию компилятора где-то надо выложить деньга на 25 лицензий VS 2017) И даже если руководство в целом одобряет такие траты, нужно как-то доказать что они оправданы, пусть даже без чиселок с графиками и прочего ROI булшита)
Дело не в том что руководство запрещает что-то использовать, скорее наоборот в предоставлении этой самой свободы.
(и да, я даже не буду обсуждать вариант «а давайте только части разработчиков новую версию дадим», это еще хуже чем не обновлять ничего вовсе)
Но мне на последних трех работах постоянно советуют освоить что-то кроме vim. :-)
msvc сейчас лучше и быстрее всех внедряют новые фичи языка, буквально весной msvc полнее всех остальных компиляторов поддерживал c++17
май 2017-ого года: выходит gcc 7 с полной поддержкой c++17
декабрь 2017-ого года: стандарт с++17 официально опубликован
май 2018-ого: выходит msvc 15.7 с полной поддержкой с++17
ноябрь 2018-ого: некий vladon утверждает, что msvc впереди планеты всей
актуальные сводные таблицы по поддержке стандартов компиляторами можете посмотреть здесь: gcc/clang. MSVC опять впереди планеты всей — у них эти таблички надо искать в записях в блоге, например этой.
>в gcc8 есть.
Мда я думал полная поддержка это когда все положения стандарта и библиотеки реализованы
Дело не в том что это нельзя «пощупать». Дело в том что внедрить это в сколько-то значимых масштабах — боль.
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.
habr.com/post/428930
Я посмотрел да сравнил, там у автора примеры есть.
Действительно, зачем иметь дома отдельно нож, ножницы, пилочку и пинцет, если всё это можно заменить одним швейцарским?
«А давайте запросы к базе данных писать на плюсах.»
Поскольку большинство сложных продуктов состоят сейчас из различных клиентов, файл серверов, серверов данных и серверов приложений, работающих к тому-же на разных платформах, сложно представить себе единый инструмент под все задачи.
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.
В плане дизайна объектов Delphi ближе к C#, чем к С++, т.к. разделяет классы и структуры, а также допускает легковесное множественное наследование интерфейсов.
Я не считаю это недостатком: классам с виртуальными методами не место на стеке.
А вот отсутствие RAII — проблема.
классам с виртуальными методами не место на стеке.Интересно, почему? Так можно сказать: «классам с приватными полями не место на стеке», или назвать любое другое ограничение.
Наверное, всё дело в том, что многие полезные фишки языка, повышающие производительность, также серьёзно повышают и риски, которые себя не оправдывают?
Наверное, всё дело в том, что многие полезные фишки языка, повышающие производительность, также серьёзно повышают и риски, которые себя не оправдывают?
Ды нет вон в 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]?
А дело в опечатке, которую ни я, ни множество более опытных программистов не заметили: EPS=.1-E5 вместо EPS=.1E-5
В том же С# есть такие ошибки
За счёт более сильной типизации (в C# нет автоматического приведения типов к bool) описка чаще приводит к ошибке компиляции.
Были бы столь же оптимизированные компиляторы у Бейсика, вы бы писали на БейсикеДело в самой концепции языка C/C++ — не платить за то, чем не пользуешься. Например, хочешь — используй строки, а хочешь — указатели в память на цепочки символов. Хочешь — размещай в стеке, хочешь — в куче, а если надо, стандартным контейнерам дай свой аллокатор и управляй размещением, как оптимально для задачи.
Дело не сколько в оптимизирующем компиляторе, сколько в перекладывании на программиста массы микро-решений, влияющих на производительность, которые компилятор не может принять сам. Но в этом и сложность писать на C/C++.
Скажем в Delphi никто не запрещает использовать вместо классов в кучеЕсть множество чужих классов, из той же VCL, которые программист не может превратить в структуры. Да и со своими тоже не сможет, если уже куча кода использует их как классы.
что касается аллокации, то там она осуществляется методами, которые при желании можно перекрыть и разложить всё так, как душе угодноЭто в стандарте языка, или надо лезть в кишки реализации? Есть библиотеки типа FastMM, но они частично на ассемблере, и сильно связаны с RTL.
FastMM ЕМНИП давно интегрирован в VCL.
Есть TObject от которого наследуются все, и у него есть NewInstance.Это кривое решение, потому что смешивает логику объекта и логику его размещения. В C++, например, есть синтаксис new, который позволяет создать (выделить память) с помощью указанного аллокатора, и другой объект этого же класса — другим аллокатором, например, стандартным.
FastMM ЕМНИП давно интегрирован в VCL.Если мне надо будет написать свой, но чтобы он выделял не только мои объекты с кастомным NewInstance, а строки, к примеру?
Но писать свой менеджер памяти, это как-то слишком крутовато, сдается мне даже на плюсах таким не страдают.
Скажем в Delphi никто не запрещает использовать вместо классов в куче, структуры на стеке
А разве структуры могут иметь наследование и методы?
Собственно в этом, я полагаю, и видят основную проблему ООП те, кто его критикуют. Далеко не всегда эта самая общность, оправдывающая наследование выстраивается очевидным образом, и на первый план выходит алгоритм.
допустим юнит в стратежке можно спокойно описать структурой и работать с ним не как с некой цельной сущностью, как, например, с классом соединения с базой данных, а как с данными.
Отлично а если разновидностей этих юнитов куча, а поведение наполовину перекрывается. а работать с ними по сути нужно одинаково?
Нету. Как и конструктора.
Ах да в дельфях ещё нет 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% уязвимостей связано с переполнением буфера, размещенного в стеке. Потому, что так «эффективнее».
Если уж размещать для ускорения буфер в стеке, то от проверки придется отказаться.
В общем так: опасная работа с буфером быстрее в стеке, а безопасная в куче.
После каждого полученного и записанного байта подсчитывает оставшееся в буфере место.
Вот на этой проверке и экономят.
В куче возможно создать прерывание по выходу за пределы выделенной памяти. Сложно, но тогда проверять на каждом шаге есть ли еше место не требуется. Достаточно обработать прерывание в случае недостатка места в буфере.
В куче возможно создать прерывание по выходу за пределы выделенной памятиКаким образом? Можете привести пример кода?
И что она с размером делает если, например, получает входящую информацию побайтно? После каждого полученного и записанного байта подсчитывает оставшееся в буфере место.
Как реализована эта функция внутри — это её дело. Нам лишь достаточно знать, что ей на вход подаётся адрес буфера и его размер, она же гарантирует, что не будет выходить за границы буфера.
Вот на этой проверке и экономят.
Ошибки переполнения буфера возникают из-за того, что либо неправильно вычисляется сам размер буфера, либо используются функции, которые вообще не имеют такого параметра, как размер буфера (например, 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-летней давности, разве что формат проекта мог поменяться, а языковые конструкции совместимы.
Насчет компонентов вообще, то в свое время было модно делать в виде компонентов абсолютно всё, даже то, что не было никакого смысла интегрировать в среду и бросать на форму. Ну и была мода на разного рода декоративные свистелки и перделки.
Другая причина, почему может не компилироваться, некоторые изменения в VCL, но, объективно там был маразм, который стоило выбросить, и уже давно всех предупреждают за несколько лет метками deprecated.
При этом работаем мы все-таки не с абстрактным языком, а с конкретным инструментом. И совершенно безотносительно языка мы можем использовать библиотеку 10-тилетней давности, которая перестанет нормально работать с очередной обновой ОС.
Вот так там начинается fr.inc:
{******************************************}
{ }
{ FastReport v2.5 }
{ Include file }
{ }
{Copyright(c) 1998-2003 by FastReports Inc.}
{ }
{******************************************}
А где можно глянуть вашу версию? Сходу найти не получается. Попробую ее сконвертировать под Delphi 10.2 и Lazarus, у меня в этом есть опыт.
github.com/VencejoSoftware/FreeReport
github.com/jciberta/FreeReport
На самом деле, Паскалевская передача аргументов позволяет генерировать код короче, но не поддерживает функции с переменным числом аргументов (как требует, например,
printf
). Поэтому этот способ передачи параметров был способом оптимизации в старых компиляторах си.Сейчас PASCAL переименован в __stdcall и в этом виде до сих пор здравствует.
Вот решение куда короче и надёжнее, хоть и требует для каждой комбинации аргументов отдельную строчку в импорте.
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';
...
А stdcall — не pascal, и в Delphi используется другие соглашения. Так что не вброс.
Вот цитата из википедии:
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).
Both the languages Pascal and x86 assembly had been heavily used in earlier versions of the Windows API«API», т.е. интерфейсная часть, не реализация.
{*******************************************************}
{ }
{ Borland Delphi Run-time Library }
{ Win32 API Interface Unit }
{ }
{ Copyright (c) 1985-1999, Microsoft Corporation }
{ }
{ Translator: Borland Software Corporation }
{ }
{*******************************************************}
Еще раз: разработку 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)
и всякие косяки со скобками {} — вполне себе зависит.
Аккуратно пользоваться операторами надо везде. В 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);
Если вы пишете код не для себя, а для других, тогда придётся смириться с тем, что писать легкочитаемый код важнее.
От своего мнения о деятельности Вирта после изобретения Паскаля, я вас избавлю, по причине врожденных лени и вежливости.
Но в нормальных модулях есть еще и настройка доступа, а так же инициализация и финализация. Что делает их похожими на классы…
Или оттенки и степени прилагательных. «Хороший» — для кого хороший? А «плюсовой» исключает субъективность. Опять же, если вам нужно что-то сильнее «плюсового», какой смысл иметь целый набор расплывчатых бесполезных слов — «великолепный», «отличный» и так далее? «Плюс плюсовой» охватывает те же значения, а если нужно ещё сильнее — «плюсплюс плюсовой». Конечно, мы и сейчас уже пользуемся этими формами, но в окончательном варианте новояза других просто не останется. В итоге все понятия плохого и хорошего будут описываться только шестью словами, а по сути, двумя.Оруэлл. 1984
Жизнь С++