Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
А когда он не менялся, со всех сторон было "язык умер! желанную фичу не добавляют! как можно пользоваться языком застрявшим в 90-х!". Всем не угодишь
ЕМ>Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
Я че-т не понимаю, вам кто-то зажал пальцы в дверь и заставляет использовать С++ что ли?
Здравствуйте, RonWilson, Вы писали:
ЕМ>>Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
RW>Если уж и создатель его не особо понимает (писал тут кто-то про это), то это шедевр
C++20 is the first release of C++ that added a feature that made the standard smaller. When I talk about the importance of simplifying C++ by judiciously adding features that let programmers express their intent directly, some people legitimately object that adding a feature makes C++ bigger and more complex. I reply “but it makes C++ code simpler” and “if it replaces something more complex then we can teach a simpler C++ for new code,” but those effects have been hard to measure concretely. Now in C++20 for the first time we added a new feature that made the standard smaller: We added the C++20 spaceship operator to the language, but we also applied it throughout the C++ standard library and that made the library specification nearly 20 pages shorter — a net reduction. So for the first time we can measure that, yes, adding a feature to C++ can make C++ smaller.
Мелочь, а приятно. И там же выше он пишет, что
C++20 is the first ever “D&E-complete” release of C++. In February, we completed C++20, which is the first release of Standard C++ that includes every feature that Bjarne Stroustrup envisioned for C++’s evolution in his 1994 book The Design and Evolution of C++ (aka D&E), including concepts, coroutines, modules, and more, except only for one minor feature (unified function call syntax).
Оба примера, на мой взгляд, сравнимы с началом раздела "16 Library introduction" на странице 458 в стандарте C++20, особенно учитывая, что стандартная библиотека С++ содержит в себе и всю библиотеку С впридачу.
Здравствуйте, Marty, Вы писали:
M>Я под STM32 на 11ом пишу, есть люди, которые на шаблонах C++ 17го стандарта с constexpr'ами фигачат. И, кстати, орчень эффективно выходит, по сравнению с более ранними стандартами
Вряд ли дело в стандартах — скорее всего, просто оптимизаторы стали лучше работать.
M>На других языках что, лучше понимают, что "у программы внутри"? Лучше без профайлера понимают, как писать эффективно?
У большинства других языков это попросту не входит в парадигму. Уникальность C — в том, что в нем принципиально нет языковых конструкций, могущих породить объемный и/или тормозной код. C++ это унаследовал, и единственной чисто языковой фичей, которая могла дать избыточный код или тормоза, были исключения. Но их и невозможно было реализовать иначе, поэтому к ним нет претензий.
А вот когда вдруг обнаружилось, что на шаблонах можно делать то, что в других условиях обязан делать сам язык — получение сведений о типах/объектах, их взаимосвязях и прочие compile-time сервисы — и этот подход был признан правильным, тогда и началась вакханалия. Большинство ведь толком не понимает, как работает шаблонная рекурсия, завязанная на SFINAE, поэтому тупо копирует рекомендованные конструкции из учебников; если после этого вылезают странные ошибки — жалуются в форумах, где им советуют "поправить вот здесь вот так". А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных. И вместо прозрачного языка с контролируемым объемом и быстродействием программы получается еще один "язык выражения намерений программиста", которых и без того множество.
M>Чем тебе стандартная библиотека, и её развитие, не нравится — тоже не понятно.
Тем, что она давно подмяла язык под себя, предложив извращенную реализацию того, что должно быть нормально реализовано в компиляторе. По уму, ее давно нужно было выделить в отдельный стандарт и разбить на уровни, реализация которых опциональна.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>При таком подходе на языке можно с одинаковым удобством и эффективностью писать программы для простейших микроконтроллеров, ядра ОС, драйверы, мелкие программы и навороченные комплексы.
Вообще-то это всё актуально и сейчас
ЕМ>А потом среди поклонников (и разработчиков стандарта) возобладал традиционный подход к ЯП — "чтобы реализовать такой-то алгоритм, нужно написать вот это и вот это". Подавляющее большинство C++-программистов уже давно не понимает, что у программы внутри, как она взаимодействует со средой выполнения, какие конструкции порождают компактный код, а какие — развесистый, не умеет оптимизировать без профайлера и т.п., а просто кодирует алгоритм мало-мальски подходящими конструкциями языка и стандартной библиотеки, которая тоже превратилась в паровоз, нахлобученный на легковушку.
Как C++ программист который таки "понимает, что у программы внутри, как она взаимодействует со средой выполнения, какие конструкции порождают компактный код, а какие — развесистый" — могу с полной ответвенностью заявить, что новые стандарты таки упрощают мою работу, а не усложняют.
И если по той или ной причине вдруг приходится использовать предыдущие версии, то постоянно натыкаюсь на места которые с новыми фичами можно выразить намного проще, лаконичнее и понятнее
Или например с ужасом вспоминаю ::result протокол
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Не хотели C++? получите лютую и беспощадную смесь макросов и _Generic, ешьте не обляпайтесь
Тут я согласен, что у чистых сишников довлеет какая-то религиозная неприязнь ко всему, что есть в C++. Как у французов: пусть криво, зато не как у англичан.
Здравствуйте, lpd, Вы писали:
lpd>Очень интересно, что за софт такой пишут любители сложных шаблонов и мув-семантики, что классического С++ им не хватает?
Очень интересно, что за софт такой пишут любители классического C++, что классического С11 им не хватает?
Очень интересно, что за софт такой пишут любители классического C11, что классического K&R C им не хватает?
Очень интересно, что за софт такой пишут любители классического K&R C, что классического макро-ассемблера им не хватает?
Очень интересно, что за софт такой пишут любители классического макро-ассемблера, что классических ассемблера им не хватает?
Очень интересно, что за софт такой пишут любители классического ассемблера, что классических машинных кодов им не хватает?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, ioni, Вы писали:
I>>Вроде как этот? I>>https://isocpp.org/files/papers/N4860.pdf
ЕМ>Интересно, это 1800 страниц — это рекорд по объему стандарта на язык программирования, или есть больше?
Язык там описан на 458 страницах. Остальное -- вредный довесок в виде "стандартной библиотеки". Торговля с нагрузкой.
ЕМ>У большинства других языков это попросту не входит в парадигму. Уникальность C — в том, что в нем принципиально нет языковых конструкций, могущих породить объемный и/или тормозной код. C++ это унаследовал, и единственной чисто языковой фичей, которая могла дать избыточный код или тормоза, были исключения. Но их и невозможно было реализовать иначе, поэтому к ним нет претензий.
Вот тут ты абсолютно прав и на 100% попал в точку. Множество людей работающих близко к железу иногда даже сами не понимают за что они любят С. А вот именно за то, (не буквально но суть отражает) что быстро окинув код взглядом можно тут же оценить насколько это быстро и насколько это много в ассемблерном выхлопе, а это очень важно в их работе и зачастую является ключевым фактором. Однако это верно только если мы сами пишем код и досконально знаем каждый метод и что примерно делает каждая функция и знаем цену сторонних функций которые вызываем. То же можно сказать о С++ коде. Если ты сам пишешь весь код, то ты вполне в состоянии его контролировать. Если ты используешь сторонний код, то должен быть уверен в его эффективности.
ЕМ>А вот когда вдруг обнаружилось, что на шаблонах можно делать то, что в других условиях обязан делать сам язык — получение сведений о типах/объектах, их взаимосвязях и прочие compile-time сервисы — и этот подход был признан правильным, тогда и началась вакханалия. Большинство ведь толком не понимает, как работает шаблонная рекурсия, завязанная на SFINAE, поэтому тупо копирует рекомендованные конструкции из учебников; если после этого вылезают странные ошибки — жалуются в форумах, где им советуют "поправить вот здесь вот так". А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных. И вместо прозрачного языка с контролируемым объемом и быстродействием программы получается еще один "язык выражения намерений программиста", которых и без того множество.
Да, на шаблонах можно написать что угодно громоздкое, особенно если задаться этой целью, как и на С . Но шаблоны это мета-програмирование, это программирование языка программирования и 90% случаев весь код выполняется на этапе компиляции и ничего не отнимает ни в плане скорости ни в плане размера программы. Непринятие "чистыми" С программистами шаблонов С++ основывается на их профессиональной привычке, что много кода — медленно, большой объем программы. Это не более чем привычка.
Я вполне согласен что системщикам не нравится неявные вызовы new/delete или исключения, тем более в ядре, где невозможно явно контролировать реализацию. Ну так и не используйте их. Зато в современном С++ появилась масса вещей которые можно делать прямо во время компиляции и с помощью которых можно автоматизировать написание большого объема почти одинакового кода, которой на С все-равно придется писать.
Чем, например системному программисту может навредить RAII? Если вы не используете динамическое аллоцирование (new/delete), то и исключений в конструкторе быть не может.
Чем вам помешают STL-ные: array, string_view, optional, variant ? Там гарантированно не будет никаких аллокаций и исключений если вы их не используете в своих классах.
Чем плох constexr ?
ЕМ>Тем, что она давно подмяла язык под себя, предложив извращенную реализацию того, что должно быть нормально реализовано в компиляторе. По уму, ее давно нужно было выделить в отдельный стандарт и разбить на уровни, реализация которых опциональна.
Да это и так все уже давно сделано. Не включай не нужные заголовки, не включай RTTI, не используй new/detete. Будет тебе по скорости тот же С, только намного мощнее и с шаблонами. Я, например, вообще не использую ужасно спроектированное тормозное и неудобное I/O. Можешь — используешь vector, string, map. Хочешь — пиши свои. Но зато, часто на практике, по самой задаче просто нужно написать много "шаблонного" кода. Обычно это какие-то табличные вещи, таблицы маршрутизации, какие-то множества структур. Тут С не может дать ничего в помощь разработчику. Начинается кто в лес кто по дрова: какие-то препроцессоры, сторонние генераторы и т.д.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Но когда нужно модифицировать стандартный шаблон или сделать свой на похожих принципах, из-за того же непонимания механизма лепятся конструкции "лишь бы заработало". Как только заработало — задача считается решенной, даже если вызов разворачивается в "ужас-ужас", но кто смотрит, во что оно развернулось?
Я бы сказал, что это подмена понятий. Потому что язык C++ сам по себе тут не при чем. И даже программирование тут не при чем.
Такие люди есть во всех отраслях, это вопрос профпригодности по большому счету.
PS. Я понимаю, что имелось в виду, что "С++ провоцирует лепить конструкции "лишь бы заработало", но я с этим не согласен по причине демагогичности заявления: всегда есть некий уровень в любом деле, до которого не дотягиваются (не могут или не хотят) N специалистов, что и порождает с их стороны подобную работу "на отстань". Использовать это как аргумент в обвинении конкретного инструмента совершенно некорректно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
Если уж и создатель его не особо понимает (писал тут кто-то про это), то это шедевр
Здравствуйте, kaa.python, Вы писали:
KP>А когда он не менялся, со всех сторон было "язык умер! желанную фичу не добавляют! как можно пользоваться языком застрявшим в 90-х!".
Так и надо было развивать язык в рамках подхода, обеспечившего успех и C, и C++ — всю работу выполняют функции, а встроенные средства языка лишь определяют сущности и операции над ними. При таком подходе на языке можно с одинаковым удобством и эффективностью писать программы для простейших микроконтроллеров, ядра ОС, драйверы, мелкие программы и навороченные комплексы. В этом была уникальность языка и основная причина его популярности.
А потом среди поклонников (и разработчиков стандарта) возобладал традиционный подход к ЯП — "чтобы реализовать такой-то алгоритм, нужно написать вот это и вот это". Подавляющее большинство C++-программистов уже давно не понимает, что у программы внутри, как она взаимодействует со средой выполнения, какие конструкции порождают компактный код, а какие — развесистый, не умеет оптимизировать без профайлера и т.п., а просто кодирует алгоритм мало-мальски подходящими конструкциями языка и стандартной библиотеки, которая тоже превратилась в паровоз, нахлобученный на легковушку. Для всего этого уже было 100500 самых разных языков, и регулярно появляются новые, какой был смысл тащить туда еще и C++?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>При таком подходе на языке можно с одинаковым удобством и эффективностью писать программы для простейших микроконтроллеров, ядра ОС, драйверы, мелкие программы и навороченные комплексы.
Нет, навороченные комплексы даже на "Си с классами" было сложно делать. Хотя и проще, чем на чистом Си. Но реально удобно это стало делать лишь после того как C++ приобрел основные черты C++98, т.е. обзавелся шаблонами и исключениями. Вся последующая эволюция С++ до C++17 включительно -- это лишь доведение C++98 до ума. Кардинальные перемены могут наступить в C++20 с его модулями, концептами, operator<=>, короутинами.
ЕМ>В этом была уникальность языка и основная причина его популярности.
Скорее просто на момент завоевания популярности у C++ не было достойных конкурентов, которые бы сочетали достаточную выразительность и высокую эффективность. Что в условиях слабых компьютеров тех лет было чрезвычайно важным конкурентным преимуществом. Но оно стало таять уже где-то к концу 1990-х.
PM>C++20 is the first ever “D&E-complete” release of C++. In February, we completed C++20, which is the first release of Standard C++ that includes every feature that Bjarne Stroustrup envisioned for C++’s evolution in his 1994 book The Design and Evolution of C++ (aka D&E), including concepts, coroutines, modules, and more, except only for one minor feature (unified function call syntax).
Ничего себе, minor feature (UFCS). В сравнении с концептами — может быть, но эта штука давно присутствует в других языках и давно ожидаема в С++.
PM>>C++20 is the first ever “D&E-complete” release of C++. In February, we completed C++20, which is the first release of Standard C++ that includes every feature that Bjarne Stroustrup envisioned for C++’s evolution in his 1994 book The Design and Evolution of C++ (aka D&E), including concepts, coroutines, modules, and more, except only for one minor feature (unified function call syntax).
F>Ничего себе, minor feature (UFCS). В сравнении с концептами — может быть, но эта штука давно присутствует в других языках и давно ожидаема в С++.
Да, наверно UFCS вещь нужная, но для меня важнее набор перечисленных выше новых штук, которые успели зарелизить в С++20.
Почему это "даже"? Эта версия стандарта за 1000 страниц скорее всего с диффом по сравнению с предыдущей версией стандарта. В "чистом" RM Ada2012 меньше 1000 страниц.
Что логично, так как при разработке Ады не было требования тащить совместимость с AT&T'шным уродцем, C, и язык получился более целостным и самостоятельным с т.з. парадигмы.
Здравствуйте, Евгений Музыченко, Вы писали:
RW>>Даже Ada отдыхает со своими 1186 листиков
ЕМ>Меня последние годы не покидает стойкое сомнение в психической адекватности этих людей. Уже давно понятно, что C++ превратился в уродливого монстра, даже полное изучение и использование которого требует непомерных затрат, не говоря уже о реализации и поддержке, но они упорно двигают его все дальше и дальше.
Не нравится — не пользуйся. По мне так — пользоваться просто, и целиком всё знать необязательно
ЗЫ И да, мне нравится, что язык стал активно развиваться, и то, что код написанный 20 лет назад собирается и работает точно так же, как и раньше
Здравствуйте, Евгений Музыченко, Вы писали:
R>>вам кто-то зажал пальцы в дверь и заставляет использовать С++ что ли?
ЕМ>В целом-то я его люблю, но лишь в части более-менее адекватной реализации.
Так и пользуйся тем, что нравится. Никто же не заставляет прям всем пользоваться
Здравствуйте, Евгений Музыченко, Вы писали:
KP>>А когда он не менялся, со всех сторон было "язык умер! желанную фичу не добавляют! как можно пользоваться языком застрявшим в 90-х!".
ЕМ>Так и надо было развивать язык в рамках подхода, обеспечившего успех и C, и C++ — всю работу выполняют функции, а встроенные средства языка лишь определяют сущности и операции над ними. При таком подходе на языке можно с одинаковым удобством и эффективностью писать программы для простейших микроконтроллеров, ядра ОС, драйверы, мелкие программы и навороченные комплексы. В этом была уникальность языка и основная причина его популярности.
Я под STM32 на 11ом пишу, есть люди, которые на шаблонах C++ 17го стандарта с constexpr'ами фигачат. И, кстати, орчень эффективно выходит, по сравнению с более ранними стандартами
ЕМ>А потом среди поклонников (и разработчиков стандарта) возобладал традиционный подход к ЯП — "чтобы реализовать такой-то алгоритм, нужно написать вот это и вот это". Подавляющее большинство C++-программистов уже давно не понимает, что у программы внутри, как она взаимодействует со средой выполнения, какие конструкции порождают компактный код, а какие — развесистый, не умеет оптимизировать без профайлера и т.п., а просто кодирует алгоритм мало-мальски подходящими конструкциями языка и стандартной библиотеки, которая тоже превратилась в паровоз, нахлобученный на легковушку. Для всего этого уже было 100500 самых разных языков, и регулярно появляются новые, какой был смысл тащить туда еще и C++?
Куча непонятных заявлений. На других языках что, лучше понимают, что "у программы внутри"? Лучше без профайлера понимают, как писать эффективно?
"просто кодирует алгоритм мало-мальски подходящими конструкциями языка и стандартной библиотеки" — вообще-то этим занимаются большинство программистов всегда, а на других языках — так вообще это число ассимтотически приближается к 100%
Чем тебе стандартная библиотека, и её развитие, не нравится — тоже не понятно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Большинство ведь толком не понимает, как работает шаблонная рекурсия, завязанная на SFINAE, поэтому тупо копирует рекомендованные конструкции из учебников; если после этого вылезают странные ошибки — жалуются в форумах, где им советуют "поправить вот здесь вот так". А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных. И вместо прозрачного языка с контролируемым объемом и быстродействием программы получается еще один "язык выражения намерений программиста", которых и без того множество.
Просто интересно стало, на чем основаны эти утверждения про большинство. Как ты статистику собирал?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Я под STM32 на 11ом пишу, есть люди, которые на шаблонах C++ 17го стандарта с constexpr'ами фигачат. И, кстати, орчень эффективно выходит, по сравнению с более ранними стандартами
ЕМ>Вряд ли дело в стандартах — скорее всего, просто оптимизаторы стали лучше работать.
Из-за constexpr'а, да
M>>На других языках что, лучше понимают, что "у программы внутри"? Лучше без профайлера понимают, как писать эффективно?
ЕМ>У большинства других языков это попросту не входит в парадигму. Уникальность C — в том, что в нем принципиально нет языковых конструкций, могущих породить объемный и/или тормозной код. C++ это унаследовал, и единственной чисто языковой фичей, которая могла дать избыточный код или тормоза, были исключения. Но их и невозможно было реализовать иначе, поэтому к ним нет претензий.
И в чем проблема?
ЕМ>А вот когда вдруг обнаружилось, что на шаблонах можно делать то, что в других условиях обязан делать сам язык — получение сведений о типах/объектах, их взаимосвязях и прочие compile-time сервисы — и этот подход был признан правильным, тогда и началась вакханалия. Большинство ведь толком не понимает, как работает шаблонная рекурсия, завязанная на SFINAE, поэтому тупо копирует рекомендованные конструкции из учебников; если после этого вылезают странные ошибки — жалуются в форумах, где им советуют "поправить вот здесь вот так". А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных. И вместо прозрачного языка с контролируемым объемом и быстродействием программы получается еще один "язык выражения намерений программиста", которых и без того множество.
Я вот, например, в токостях и сейчас не понимаю часто, как работает SFINAE, и без шаблонных рекурсий
Современные версии всю эту возню со SFINAE упрощают/заменяют
M>>Чем тебе стандартная библиотека, и её развитие, не нравится — тоже не понятно.
ЕМ>Тем, что она давно подмяла язык под себя, предложив извращенную реализацию того, что должно быть нормально реализовано в компиляторе. По уму, ее давно нужно было выделить в отдельный стандарт и разбить на уровни, реализация которых опциональна.
Ничего она не подмяла. Под кейл, вон, армовский только компилер 11 версии стандарта, а либа — еще RogueWave от девяносто лохматого года. И нормально, в общем-то, живётся
Здравствуйте, so5team, Вы писали:
ЕМ>>А привыкнув к такому подходу, начинает столь же бездумно лепить шаблонные конструкции для организации/обработки данных.
S>Можно пример подобного?
Я сам такое не практикую, поэтому конкретных примеров под рукой нет, но встречается это часто. Сами-то конструкции комбинировать несложно, и это нередко даже выглядит изящно, но несколько вложенных уровней разворачиваются в неслабого объема код, уменьшить который не всякий оптимизатор способен.
Здравствуйте, rg45, Вы писали:
R>Просто интересно стало, на чем основаны эти утверждения про большинство. Как ты статистику собирал?
Может, конечно, это и иллюзия, но вопросы типа "а почему так?" и жалобы на "не работает" встречаются часто и обильно. И с институтских времен помню, что теория формальных языков у большинства шла с большим скрипом, у них в голове не укладывалось, каким образом правило что-то там порождает. Оно и понятно — мышление физически заточено под итеративные конструкции, а не рекурсивные. Но традиционная для ЯП "исполняемая" рекурсия обычно легко сводится к итерации, поэтому ее легче понять. А вот когда она "порождающая" — у большинства как раз крыша и едет.
Уточняю: "большинство" — это среди всех программистов, а не только успешных и результативных.
Здравствуйте, Евгений Музыченко, Вы писали:
S>>Можно пример подобного?
ЕМ>Я сам такое не практикую, поэтому конкретных примеров под рукой нет, но встречается это часто. Сами-то конструкции комбинировать несложно, и это нередко даже выглядит изящно, но несколько вложенных уровней разворачиваются в неслабого объема код, уменьшить который не всякий оптимизатор способен.
Этот неслабого объема код только на эмбеде или в ядре имеет значение, в остальных случаях результат всё равно на порядки меньше и быстрее, чем на всяких джавах и прочих модных языках.
А в эмбеде или в ядре — ну да, нужно поаккуратнее писать
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Может, конечно, это и иллюзия, но вопросы типа "а почему так?" и жалобы на "не работает" встречаются часто и обильно. И с институтских времен помню, что теория формальных языков у большинства шла с большим скрипом, у них в голове не укладывалось, каким образом правило что-то там порождает. Оно и понятно — мышление физически заточено под итеративные конструкции, а не рекурсивные. Но традиционная для ЯП "исполняемая" рекурсия обычно легко сводится к итерации, поэтому ее легче понять. А вот когда она "порождающая" — у большинства как раз крыша и едет.
Хм. Мне вот например рекурсию написать гораздо проще, чем её развернуть в итеративный алгоритм. И сложилось впечатление, что это для большинства так
Здравствуйте, Marty, Вы писали:
ЕМ>>Вряд ли дело в стандартах — скорее всего, просто оптимизаторы стали лучше работать.
M>Из-за constexpr'а, да
Грамотному оптимизатору constexpr (как и const) не требуется — он может сам увидеть, константно ли выражение. Конструкции const/constexpr нужны больше для строгости.
M>И в чем проблема?
С исключениями — ни в чем. А с шаблонами — в том, что их давно и массово используют извращенным способом, громоздя весьма запутанные конструкции, поэтому редкий (в общей массе) программист адекватно представляет себе, во что развернется конструкция, которую он пишет в программе, и становится похожим на того юзера, который сперва жмет "предпоследнюю кнопку справа", затем выбирает "третий пункт меню", и ставит галочку в "верхней строке списка".
M>Современные версии всю эту возню со SFINAE упрощают/заменяют
Каким образом?
M>Под кейл, вон, армовский только компилер 11 версии стандарта, а либа — еще RogueWave от девяносто лохматого года.
Так это и означает "реализация языка не соответствует стандарту". А если б на язык и основные части библиотеки были отдельные стандарты, в них и разбираться было бы гораздо проще, и реализовать в полном соответствии стандарту.
Здравствуйте, Marty, Вы писали:
M>Так и пользуйся тем, что нравится. Никто же не заставляет прям всем пользоваться
Ситуация примерно такая:
Выходит новый стандарт (несколько тыщ страниц).
Появляются компиляторы, частично его реализующие.
Народ начинает внедрять новые модные фичи, по делу и без.
Обновляешь зависимости -> не компилируется ибо новые фичи
Обновляем компилятор -> упс старая ос, нужна свежая, производители компиляторов люди прогрессивные и очень занятые так что не поддерживают старые платформы.
Обновляем всё -> компилируем -> не проходит тесты
Ищем, устраняем, подстраиваемся под новыю ос -> собираем -> черт уже новый стандарт
Как плюс, проект теперь собирается только новым компилятором и на старых ос уже не пускается. А для запуска на старой ос слишком много телодвижений надо — забиваем.
Особенно хорошо это для остальных языков программирования которые собираются из плюсов. Они тоже переходят в разряд только на новых ос.
Тем самым сжигаем мосты и сами закапываем, то что работает.
А потом смотрим репозиторий: о проект не обновлялся 2года (автор помер) — всё швах использовать нельзя проект не развивается.
Когда в C++ появятся конструкции которые в явном виде ограничивают использование фич языка (как старых так и новых).
Простой вопрос как имея c++ файл определить минимальную и максимальную версию стандарта который нужен его компиляции?
Здравствуйте, Videoman, Вы писали:
V>90% случаев весь код выполняется на этапе компиляции и ничего не отнимает ни в плане скорости ни в плане размера программы.
Откуда оценка в 90%? Само собой, "чисто предикативные" шаблоны вроде is_arithmetic или is_same именно так и работают, но и они выполняются компилятором в десятки-сотни раз медленнее, чем соответствующие предикаты, будь они встроены в компилятор. А используются эти предикаты массово, в том числе во вложенных/рекурсивных шаблонах, и в итоге неслабо тормозят компиляцию.
Чтобы шаблонный код на 90% (или хотя бы на 50%) выполнялся на этапе компиляции, программист должен хорошо понимать, во что развернется та или иная шаблонная конструкция. Поскольку шаблоны в C++ традиционно используются "не благодаря, а вопреки", большинство программистов не в состоянии адекватно понять, как работают все костыли, на которых реализованы даже шаблоны из std. Но в случае непосредственного использования шаблонов из std хоть можно доверять их авторам, которые в этой кухне неплохо разбираются — там оверхед действительно небольшой. Но когда нужно модифицировать стандартный шаблон или сделать свой на похожих принципах, из-за того же непонимания механизма лепятся конструкции "лишь бы заработало". Как только заработало — задача считается решенной, даже если вызов разворачивается в "ужас-ужас", но кто смотрит, во что оно развернулось? Кстати, есть компиляторы, умеющие показать результат раскрутки шаблона в терминах языка, а не ассемблерного кода?
V>Непринятие "чистыми" С программистами шаблонов С++ основывается на их профессиональной привычке, что много кода — медленно, большой объем программы.
Лично я очень люблю шаблоны C++ в их изначальной ипостаси, как средство параметризации. Но меня тошнит от подхода "если это может быть сделано на шаблонах — давайте сделаем на шаблонах". А поскольку на шаблонах, как известно, можно сделать практически все, то большинство идей по расширению C++ выливается в добавление новых шаблонов в std.
И ладно, если бы такой подход хоть сопровождался поддержкой "метапрограммирования с человеческим лицом". Какие в языке есть средства отладочного слежения за тем, как раскручивается шаблон? Никаких. Какие есть средства диагностики ошибок, чтобы выдать пользователю шаблона осмысленное сообщение, а не вываливать потроха с кучей вспомогательных типов, классов и переменных? Опять никаких. Бассейн построили тридцать лет назад, а воду в него никак не нальют.
Да, и я уже лет двадцать пять, как не "С-программист". То же самое ООП на чистом C выглядит ничуть не лучше современного метапрограммирования на C++.
V>Я вполне согласен что системщикам не нравится неявные вызовы new/delete или исключения, тем более в ядре, где невозможно явно контролировать реализацию.
С new/delete как раз все просто — достаточно их переопределить (я так и делаю). С исключениями хуже: даже если какой-то модуль их только бросает, но нигде не обрабатывает, в языке нет законного способа определить свою функцию вместо стандартного обработчика, которая вызывалась бы в точке выброса исключения. В каждой реализации для этого нужны свои костыли.
По-хорошему, такие вещи тоже нужно документировать в стандарте, хотя бы в виде рекомендаций, чтобы в реализациях CRT не городили кто во что горазд.
V>Зато в современном С++ появилась масса вещей которые можно делать прямо во время компиляции и с помощью которых можно автоматизировать написание большого объема почти одинакового кода
Так они почти все появились не в C++, а в его std, на тех самых шаблонах. Это как если бы расширения фортрана делались главным образом через подпрограммы/функции на том же фортране.
V>Чем, например системному программисту может навредить RAII?
Ничем, оно давно и активно используется и в ядерном, и в микроконтроллерном коде. Само-то по себе оно ни ресурсов лишних не требует, ни на CRT не завязано. Подобные вещи в C++ я очень люблю.
V>Чем вам помешают STL-ные: array, string_view, optional, variant ?
Прежде всего тем, что при любой ошибке их использования компилятор, вместо осмысленного сообщения, вываливает мне потроха шаблона, и я вынужден на них смотреть, хотя совершенно этого не хочу.
V>Чем плох constexr ?
Ничем. Чисто языковые расширения я всегда приветствую, и хотел бы иметь побольше средств контроля правильности программы, но их почему-то внедряют в последнюю очередь.
ЕМ>>Тем, что она давно подмяла язык под себя, предложив извращенную реализацию того, что должно быть нормально реализовано в компиляторе. По уму, ее давно нужно было выделить в отдельный стандарт и разбить на уровни, реализация которых опциональна.
V>Но зато, часто на практике, по самой задаче просто нужно написать много "шаблонного" кода. Обычно это какие-то табличные вещи, таблицы маршрутизации, какие-то множества структур. Тут С не может дать ничего в помощь разработчику.
А что может дать C++ для удобного представления исходных таблиц в коде программы? Обрабатывать-то их и на чистом C не особо сложно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Откуда оценка в 90%? Само собой, "чисто предикативные" шаблоны вроде is_arithmetic или is_same именно так и работают, но и они выполняются компилятором в десятки-сотни раз медленнее, чем соответствующие предикаты, будь они встроены в компилятор. А используются эти предикаты массово, в том числе во вложенных/рекурсивных шаблонах, и в итоге неслабо тормозят компиляцию.
Ну так это классическая палка с двумя концами: скорость, универсальность. Так это уже давно работает везде и мы эти предикаты используем, а так это все через комитет стандартизации проходило бы годами. Понятно что тормозят, но я-то подумал раз критика в реализации мета-программирования в С++, то С может эти вопросы решать быстрее, но в С-то ничего такого и в помине нет. Особенно меня удивляет как С-шники живут без перегрузки методов:
int add_int(...)
float add_float(...)
...
По-моему это неудобно и названия методов становятся очень длинными. Смотришь на код и сразу видно что С.
ЕМ>Чтобы шаблонный код на 90% (или хотя бы на 50%) выполнялся на этапе компиляции, программист должен хорошо понимать, во что развернется та или иная шаблонная конструкция. Поскольку шаблоны в C++ традиционно используются "не благодаря, а вопреки", большинство программистов не в состоянии адекватно понять, как работают все костыли, на которых реализованы даже шаблоны из std. Но в случае непосредственного использования шаблонов из std хоть можно доверять их авторам, которые в этой кухне неплохо разбираются — там оверхед действительно небольшой. Но когда нужно модифицировать стандартный шаблон или сделать свой на похожих принципах, из-за того же непонимания механизма лепятся конструкции "лишь бы заработало". Как только заработало — задача считается решенной, даже если вызов разворачивается в "ужас-ужас", но кто смотрит, во что оно развернулось?
Не удобно, согласен, но попробуй поставить подобную задачу себе: тебе нужно сделать новую конструкцию в языке где пользователей миллионы, все они делают абсолютно разные вещи, всем нужно угодит да еще и нечего не поломать. Мне кажется что хоть язык С++ и считается системным, он на слишком разных системных уровнях используется и задача его развития изначально очень сложная, если вообще выполнимая.
По поводу шаблонов, особо не разбираясь, смотришь: если нет инстанцирования, то 100% ничего не занимает, если есть, то сложнее. Рекурсивная лапша из методов самый сложный случай, но это и на С сразу не поймешь сколько выполнятся будет.
ЕМ>Кстати, есть компиляторы, умеющие показать результат раскрутки шаблона в терминах языка, а не ассемблерного кода?
Интересный вопрос, присоединяюсь.
ЕМ>Лично я очень люблю шаблоны C++ в их изначальной ипостаси, как средство параметризации. Но меня тошнит от подхода "если это может быть сделано на шаблонах — давайте сделаем на шаблонах". А поскольку на шаблонах, как известно, можно сделать практически все, то большинство идей по расширению C++ выливается в добавление новых шаблонов в std.
Ну потому-что язык такой вот популярный, потому-что комитет... зато хоть что-до добавляется. С-шники пошли более простым путем: а давайте вообще ничего не будет делать. Ну хоть бы брали четкие, понятные вещи из С++ которые гарантированно O(n).
ЕМ>И ладно, если бы такой подход хоть сопровождался поддержкой "метапрограммирования с человеческим лицом". Какие в языке есть средства отладочного слежения за тем, как раскручивается шаблон? Никаких. Какие есть средства диагностики ошибок, чтобы выдать пользователю шаблона осмысленное сообщение, а не вываливать потроха с кучей вспомогательных типов, классов и переменных? Опять никаких. Бассейн построили тридцать лет назад, а воду в него никак не нальют.
Пока подвезли только static_assert и концепты, но ложится это все на плечи программиста: расстелить соломку везде где увидит.
ЕМ>С new/delete как раз все просто — достаточно их переопределить (я так и делаю).
Я не спорю что можно переопределить, но родные-то кидают исключения и на это все и расcчитан весь интерфейс в STL. Кроме переделки всего интерфейса я не вижу выхода.
ЕМ>С исключениями хуже: даже если какой-то модуль их только бросает, но нигде не обрабатывает, в языке нет законного способа определить свою функцию вместо стандартного обработчика, которая вызывалась бы в точке выброса исключения. В каждой реализации для этого нужны свои костыли. ЕМ>По-хорошему, такие вещи тоже нужно документировать в стандарте, хотя бы в виде рекомендаций, чтобы в реализациях CRT не городили кто во что горазд.
Согласен.
V>>Зато в современном С++ появилась масса вещей которые можно делать прямо во время компиляции и с помощью которых можно автоматизировать написание большого объема почти одинакового кода
ЕМ>Так они почти все появились не в C++, а в его std, на тех самых шаблонах. Это как если бы расширения фортрана делались главным образом через подпрограммы/функции на том же фортране.
Сделать через std банально проще и быстрее, так как бла-бла-бла...
V>>Чем вам помешают STL-ные: array, string_view, optional, variant ?
ЕМ>Прежде всего тем, что при любой ошибке их использования компилятор, вместо осмысленного сообщения, вываливает мне потроха шаблона, и я вынужден на них смотреть, хотя совершенно этого не хочу.
Надеюсь концепты в С++20 помогут.
ЕМ>А что может дать C++ для удобного представления исходных таблиц в коде программы? Обрабатывать-то их и на чистом C не особо сложно.
Я имел ввиду что ты их спокойно можешь в цикле, например, нафигачить в constexpr, как простой код без извращений, шаблонов и матриц.
Ну или:
constexpr auto tag = "bla-bla-bla..."sv;
получаешь объект почти с интерфейсом string, но гарантированно не затратив ни секунды времени, ни байта кода. Прям как в С, круто же. Или массив таких объектов.
Ну как там манглится все это под капотом меня должно интересовать только на границе модулей. Но в С-то я вынужден это делать каждую минуту, причем в ручном режиме. В библиотечном коде у меня всегда куча разных типов выполняющих семантически одну и ту же операцию. Потом перегрузка это же не только автоматически выбор имени метода, это автоматически расширяемый код. Интерфейс библиотеки не стоит же на месте. Там непрерывно появляются новые типы, новые методы. Я, честно, вообще не представляю как на С делается такое:
допустим есть уже куча готового кода и нужно сказать — делай вот все-все на 99% тоже самое, но вот с этим новым типом — вот так...
На С++ просто делается перегрузка и все, компилятор сам подставит нужный новый метод, а остальное трогать не нужно.
Здравствуйте, Videoman, Вы писали:
V>Я, честно, вообще не представляю как на С делается такое: V>допустим есть уже куча готового кода и нужно сказать — делай вот все-все на 99% тоже самое, но вот с этим новым типом — вот так...
Либо так
или просто в файле используются названия типов которые надо менять и потом
они подключаются с в исходниках с разными типами
//add.cc
NUM ADD(NUM a,NUM b) { return a+b; }
//add_int.c
#define NUM int
#define ADD add_int
#include "add.cc"
//add_float.c
#define NUM float
#define ADD add_float
#include "add.cc"
// add.h
int add_int(int,int);
float add_float(float,float);
Или кодогенерация скриптами как в opengl и генераторами как например yacc, bison для разных dsl
V>На С++ просто делается перегрузка и все, компилятор сам подставит нужный новый метод, а остальное трогать не нужно.
Ага и ненужный тоже.
Здравствуйте, Videoman, Вы писали:
V>Так это уже давно работает везде и мы эти предикаты используем, а так это все через комитет стандартизации проходило бы годами.
Так комитет в итоге их все равно принял, только в виде шаблонных реализаций в std. Всю жизнь само собой разумелось, что подобные предикаты должны быть в компиляторе, но через C++, похоже, идет обкатка подхода "что бы еще такого дурацкого сделать, чтоб весь мир пользовался?". Сильно напоминает советский анекдот "а вы их дустом не пробовали?".
V>я-то подумал раз критика в реализации мета-программирования в С++, то С может эти вопросы решать быстрее, но в С-то ничего такого и в помине нет.
Еще раз подчеркну, что я очень давно ничего не писал на C, и плохо понимаю, для чего им пользуются другие, кроме как ради небольшого количества удобств, добавленных в C99 (в C11/C17 ничего интересного не помню). Вся моя критика C++ совершенно безотносительна к C.
V>Особенно меня удивляет как С-шники живут без перегрузки методов
Да они и без классов как-то живут.
V>попробуй поставить подобную задачу себе: тебе нужно сделать новую конструкцию в языке где пользователей миллионы, все они делают абсолютно разные вещи, всем нужно угодит да еще и нечего не поломать.
Что могли бы поломать те же самые предикаты, условная трансляция на уровне языка (в том числе внутри шаблона); атрибуты типов/объектов/функций, наследуемые по цепочке использования; операции добавления/удаления константности у типа-параметра; "отложенное" добавление константности объекту, определенному выше по тексту, и подобное?
V>Мне кажется что хоть язык С++ и считается системным, он на слишком разных системных уровнях используется и задача его развития изначально очень сложная, если вообще выполнимая.
Именно поэтому правильнее было бы ввести в язык побольше простых в реализации и использовании средств для описания свойств элементов программы, операций с этими свойствами, и управления обработкой программы. С этого ведь и начиналось: const/volatile — для описания свойств объектов, классы — для описания свойств типов, перегрузка — для описания свойств операций и одноименных функций. Но с той же перегрузкой в конечном счете облажались: вместо явной возможности введения правил вывода, которая упростила бы и программирование, и компиляцию, придумали длинный и запутанный набор стандартных правил, которые все время хочется обойти. А уж сочетание этих правил с шаблонами — вообще неимоверный ужас. Но ведь они все это трудолюбиво тянут.
V>Рекурсивная лапша из методов самый сложный случай, но это и на С сразу не поймешь сколько выполнятся будет.
Обычные методы можно в отладчике обойти, или хоть отладочных печатей наставить.
V>Пока подвезли только static_assert и концепты, но ложится это все на плечи программиста: расстелить соломку везде где увидит.
А давно пора добавить, например, автоматический вызов специальных методов (например, check ()) в определенных точках (скажем, в начале/конце основных методов класса, при передаче объекта в функцию, при возврате из функции и т.п.). Расходы мизерные, зато крайне полезно при отладке.
V>Я не спорю что можно переопределить, но родные-то кидают исключения и на это все и расcчитан весь интерфейс в STL. Кроме переделки всего интерфейса я не вижу выхода.
Вообще, ядро NT поддерживает системные (структурные) исключения, они там используются кое-где, но не массово. Технически нет проблем реализовать в ядерной версии CRT и полноценные исключения C++, и всю std, но подозреваю, что этого не делают умышленно, дабы писатели драйверов на "интуитивно-понятных" фреймворках типа KMDF совсем уж не распоясались.
V>Я имел ввиду что ты их спокойно можешь в цикле, например, нафигачить в constexpr, как простой код без извращений, шаблонов и матриц.
Это удобно, хотя многое из такого оптимизаторы уже давно умели сворачивать, но приходилось контролировать по коду.
Здравствуйте, kov_serg, Вы писали:
V>>На С++ просто делается перегрузка и все, компилятор сам подставит нужный новый метод, а остальное трогать не нужно.
_>Ага и ненужный тоже.
Это потому, что к перегрузке (и вообще автоматическому выводу) нужна возможность явного задания правил этого самого вывода.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Так комитет в итоге их все равно принял, только в виде шаблонных реализаций в std. Всю жизнь само собой разумелось, что подобные предикаты должны быть в компиляторе, но через C++, похоже, идет обкатка подхода "что бы еще такого дурацкого сделать, чтоб весь мир пользовался?". Сильно напоминает советский анекдот "а вы их дустом не пробовали?".
Я полностью разделяю твой гнев, но давай честно, ты реально за то что бы в языке вот все эти предикаты появились в виде зарезервированных слов, да еще не простых, а действующих только в пространстве имен std ?
Я себе такое слабо представляю. Уж лучше сделать нормальную диагностику для разных проблем с шаблонами, возможность вменяемо сообщать об ошибках и добавить механизм при котором все это быстро компилировалось бы, ну модули те же.
ЕМ>Что могли бы поломать те же самые предикаты, условная трансляция на уровне языка (в том числе внутри шаблона); атрибуты типов/объектов/функций, наследуемые по цепочке использования; операции добавления/удаления константности у типа-параметра; "отложенное" добавление константности объекту, определенному выше по тексту, и подобное?
Честно, я не в теме твоего предложения, но думаю что множество людей рассматривало разные варианты и решили что по другому нельзя, иначе все это просто вредительство
ЕМ>Именно поэтому правильнее было бы ввести в язык побольше простых в реализации и использовании средств для описания свойств элементов программы, операций с этими свойствами, и управления обработкой программы. С этого ведь и начиналось: const/volatile — для описания свойств объектов, классы — для описания свойств типов, перегрузка — для описания свойств операций и одноименных функций. Но с той же перегрузкой в конечном счете облажались: вместо явной возможности введения правил вывода, которая упростила бы и программирование, и компиляцию, придумали длинный и запутанный набор стандартных правил, которые все время хочется обойти. А уж сочетание этих правил с шаблонами — вообще неимоверный ужас. Но ведь они все это трудолюбиво тянут.
Это тяжелый крест обратной совместимости. Еще раз, я полностью с тобой согласен, что можно все сделать прямее и правильнее, но мы же говорим не о разработке нового языка, а о модификации языка которому уже 40+ лет.
ЕМ>Обычные методы можно в отладчике обойти, или хоть отладочных печатей наставить.
Ну шаблонные тоже обходятся в отладчике без проблем, или я не понял о чем ты. На самом деле появился еще один класс таких же "проблемных" методов — constexpr. Для их отладки я так и не придумал нормального способа кроме как где-то стыдливо объявить #define constexpr _
ЕМ>А давно пора добавить, например, автоматический вызов специальных методов (например, check ()) в определенных точках (скажем, в начале/конце основных методов класса, при передаче объекта в функцию, при возврате из функции и т.п.). Расходы мизерные, зато крайне полезно при отладке.
Не дай бог . Ведь будет также как с шаблонами, только хуже, все начнут этим пользоваться по делу и без — начнется сущий ад. Это же тоже самое что злоупотреблять перегрузкой операторов, только намного хуже.
ЕМ>Вообще, ядро NT поддерживает системные (структурные) исключения, они там используются кое-где, но не массово. Технически нет проблем реализовать в ядерной версии CRT и полноценные исключения C++, и всю std, но подозреваю, что этого не делают умышленно, дабы писатели драйверов на "интуитивно-понятных" фреймворках типа KMDF совсем уж не распоясались.
Честно мне вообще не понятно почему С++ исключения должны быть обязательно реализованы поверх "тяжелого" механизма SEH. Почему нельзя иметь возможность выбирать runtime c которым линкуешься: типа как cppruntime: static, dynamic, singlethreaded, multithreaded и т.д.
Здравствуйте, Videoman, Вы писали:
V>ты реально за то что бы в языке вот все эти предикаты появились в виде зарезервированных слов, да еще не простых, а действующих только в пространстве имен std ?
Если бы их догадались сделать хотя бы двадцать лет назад, когда идея уже оформилась (а еще лучше — тридцать, когда появились шаблоны и стало понятно, что шаблону может быть нужна информация о типах-параметрах), то идеи включать их в std даже не возникло бы. Чтобы не возникало коллизий с пользовательскими именами, можно было сделать в виде _is_xxx, или еще как-нибудь.
V>добавить механизм при котором все это быстро компилировалось бы, ну модули те же.
А как технически сделать так, чтобы рекурсивные шаблоны, глобально доступные везде, могли быстро компилироваться? Только разными видами предкомпиляции, что везде и реализуют. Или опять же реализовать все эти предикаты в компиляторе, вызывая их в виде привычных уже шаблонов.
V>Честно, я не в теме твоего предложения
Так это не для одного приложения, а практически для любого.
V>Это тяжелый крест обратной совместимости.
Чем той обратной совместимости могло помешать добавление в любой момент тех же правил выбора перегруженной версии функции? Если их делать, то так, чтобы можно было задавать как глобально, так и локально для отдельных функций.
ЕМ>>Обычные методы можно в отладчике обойти, или хоть отладочных печатей наставить.
V>Ну шаблонные тоже обходятся в отладчике без проблем, или я не понял о чем ты.
Я о раскрутке инстанцирования шаблона во время компиляции, чтобы видеть, какие подставились значения, с какими параметрами инстанцируются вложенные шаблоны, и т.п.
V>На самом деле появился еще один класс таких же "проблемных" методов — constexpr.
И для них тоже нужен какой-то выхлоп из компилятора о ходе обработки при компиляции.
ЕМ>>добавить, например, автоматический вызов специальных методов (например, check ()) в определенных точках
V>Не дай бог . Ведь будет также как с шаблонами, только хуже, все начнут этим пользоваться по делу и без — начнется сущий ад.
Так это ж сугубо для отладки, оно должно полностью управляться программистом. Во многих языках есть встроенный контроль границ массивов, диапазонов значений переменных и т.п. — это оно и есть. А так ведь некоторые умудряются пускать отладочные сборки в продакшн — что ж, из-за них не надо было вводить возможности отладочных сборок?
V>Честно мне вообще не понятно почему С++ исключения должны быть обязательно реализованы поверх "тяжелого" механизма SEH.
А как их еще можно надежно реализовать? Там же надо ловить и аппаратные исключения (ошибка доступа к памяти, переполнение, деление на нуль и т.п.). В ОС реализована полноценная раскрутка стека, это весьма обширная логика вплоть до эмуляции выполнения команд. Городить свою в CRT — будет слишком много лишнего кода. Или ограничивать стек только вызовами родных функций, скомпилированных без оптимизации стекового кадра. Тогда не получится сделать библиотеку, вызываемую, например, из паскаля, чтоб она могла вызывать паскалевские callback'и, которые, в свою очередь, могли бы вызывать функции C++.
В ядре, конечно, подобным смешиванием не занимаются, но в ответ на вызов из драйвера системной функции система вполне может вызвать одну из служебных функций драйвера, и так далее.
V>Почему нельзя иметь возможность выбирать runtime c которым линкуешься: типа как cppruntime: static, dynamic, singlethreaded, multithreaded и т.д.
Для ядра есть только multithreaded, поскольку никто не гарантирует выполнения кода строго в пределах одного потока. CRT какой-то версии MS VC++ зашит в ядро, поэтому по дефолту все драйверы линкуются к нему (некий аналог dynamic), но можно линковаться и статически, если требуется другая версия CRT.
Здравствуйте, Videoman, Вы писали:
V>Я, честно, вообще не представляю как на С делается такое: V>допустим есть уже куча готового кода и нужно сказать — делай вот все-все на 99% тоже самое, но вот с этим новым типом — вот так... V>На С++ просто делается перегрузка и все, компилятор сам подставит нужный новый метод, а остальное трогать не нужно.
В тёплой ламповой сишечьке для этого есть, барабанная дробь, дженерики! https://en.cppreference.com/w/c/language/generic
Не хотели C++? получите лютую и беспощадную смесь макросов и _Generic, ешьте не обляпайтесь
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>могу с полной ответвенностью заявить, что новые стандарты таки упрощают мою работу, а не усложняют.
Дык, тем, кто понимает, они именно упрощают. Но таких меньшинство. Большинство — тех, кто "применяет средства языка для записи алгоритма".
EP>с ужасом вспоминаю ::result протокол
Здравствуйте, Евгений Музыченко, Вы писали:
EP>>могу с полной ответвенностью заявить, что новые стандарты таки упрощают мою работу, а не усложняют. ЕМ>Дык, тем, кто понимает, они именно упрощают. Но таких меньшинство. Большинство — тех, кто "применяет средства языка для записи алгоритма".
Так если они будут применять новые средства, вместо старых монструозны альтернатив, их код тоже будет проще.
Ну и те кто что-то там не понимают — они всегда будут присутсвовать, но я за то чтобы моя работа упрощалась, и стандарт двигался именно в этом направлении, а не чтобы стандарт оберегал каких-то непонимающих от чего-то там возможного
EP>>с ужасом вспоминаю ::result протокол
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Если бы их догадались сделать хотя бы двадцать лет назад, когда идея уже оформилась (а еще лучше — тридцать, когда появились шаблоны и стало понятно, что шаблону может быть нужна информация о типах-параметрах), то идеи включать их в std даже не возникло бы. Чтобы не возникало коллизий с пользовательскими именами, можно было сделать в виде _is_xxx, или еще как-нибудь.
Не, ну ты серьезно ?! Как средства решения могут появиться раньше самой задачи. Мой ответ — скорее всего раньше софт не был таким большим и сложным.
ЕМ>Чем той обратной совместимости могло помешать добавление в любой момент тех же правил выбора перегруженной версии функции? Если их делать, то так, чтобы можно было задавать как глобально, так и локально для отдельных функций.
Ты же сам критикуешь сложность современного С++, а с таким подходом вообще ахренеешь понимать что в итоге вызывается должно. После такого просто глядя на код ты не будешь понимать что вызывается, придется еще и в коде правил разбираться. Поверь эти правила быстро станут не проще того кода на шаблонах который тебе не нравится, а потом ты еще и средства анализа самих правил захочешь .
ЕМ>Я о раскрутке инстанцирования шаблона во время компиляции, чтобы видеть, какие подставились значения, с какими параметрами инстанцируются вложенные шаблоны, и т.п.
Да, это очень интересный вопрос, я бы сам хотел что-то иметь в помощь от компилятора.
ЕМ>Так это ж сугубо для отладки, оно должно полностью управляться программистом. Во многих языках есть встроенный контроль границ массивов, диапазонов значений переменных и т.п. — это оно и есть. А так ведь некоторые умудряются пускать отладочные сборки в продакшн — что ж, из-за них не надо было вводить возможности отладочных сборок?
Если что-то типа ассертов, то я согласен. Но ведь будут тут ныть на форуме: чего это дебажный код работает так медленно, невозможно отлаживаться. Кто-то тут ныл уже, не помню
ЕМ>А как их еще можно надежно реализовать?
А не надо всегда надежно. Просто другой режим. Если я работаю только с С++ и мне нужны быстрые исключения, то я их выбираю.
ЕМ>Там же надо ловить и аппаратные исключения (ошибка доступа к памяти, переполнение, деление на нуль и т.п.). В ОС реализована полноценная раскрутка стека, это весьма обширная логика вплоть до эмуляции выполнения команд. Городить свою в CRT — будет слишком много лишнего кода.
Ну С-то как-то с этим всем работает без исключений. Пусть будут просто обработчики. Если их нет то std::terminate и все тут. Или если ты так близко с железу работаешь, то используй средства OC и скорее всего ты уже и сами исключения в таком случае не будешь использовать.
ЕМ>Или ограничивать стек только вызовами родных функций, скомпилированных без оптимизации стекового кадра. Тогда не получится сделать библиотеку, вызываемую, например, из паскаля, чтоб она могла вызывать паскалевские callback'и, которые, в свою очередь, могли бы вызывать функции C++.
Универсальное средство почти всегда не гибкое. Дайте выбор. Мне вот, например, никогда функцию из паскаля не приходилось вызывать (если не считать что все dll pascal по-умолчанию . Типа-драйвера разные я писал только в режиме пользователя и SEH использовал только платформозавичимый: __try, __catch по-моему.
ЕМ>Для ядра есть только multithreaded, поскольку никто не гарантирует выполнения кода строго в пределах одного потока. CRT какой-то версии MS VC++ зашит в ядро, поэтому по дефолту все драйверы линкуются к нему (некий аналог dynamic), но можно линковаться и статически, если требуется другая версия CRT.
Это все понятно, тут спору нет. Но мы же вообще про С++ рассуждаем.
Здравствуйте, Videoman, Вы писали:
ЕМ>>Я о раскрутке инстанцирования шаблона во время компиляции, чтобы видеть, какие подставились значения, с какими параметрами инстанцируются вложенные шаблоны, и т.п. V>Да, это очень интересный вопрос, я бы сам хотел что-то иметь в помощь от компилятора.
https://cppinsights.io/ может в ряде случаев немного помочь, например можно посмотреть во что инстанциируются шаблонные функции и структуры
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>При таком подходе на языке можно с одинаковым удобством и эффективностью писать программы для простейших микроконтроллеров, ядра ОС, драйверы, мелкие программы и навороченные комплексы.
EP>Вообще-то это всё актуально и сейчас
Очень интересно, что за софт такой пишут любители сложных шаблонов и мув-семантики, что классического С++ им не хватает?
Лично я когда занимался кодеками видео/графики, хорошо видел, что оптимизация алгоритма на порядки эффективнее, чем возня с тонкостями языка программирования.
Теперь снова занимаюсь ядром линукса, и от классов с наследованием бы не отказался, но вполне нормально можно жить и без него, на С, с указателями вместо методов и счетчиками ссылок. И возникающие в процессе работы проблемы С++, тем более современный, не решил бы.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Очень интересно, что за софт такой пишут любители сложных шаблонов и мув-семантики, что классического С++ им не хватает? lpd>Лично я когда занимался кодеками видео/графики, хорошо видел, что оптимизация алгоритма на порядки эффективнее, чем возня с тонкостями языка программирования.
Ты путаешь мягкое с тёплым, одно другому не мешает, не противоречит, и не исключает. Например когда занимался обработкой и сжатием граничных представлений, в том числе R&D — там были важны и алгоритмы и структуры данных, и возможность обобщённой И эффективной реализации — здесь как раз C++ проявляется в полный рост. В других прикладных областях наблюдаю абсолютно тоже самое.
В том числе и в графике: https://www.youtube.com/watch?v=sR8Wjg0pceE
lpd>Теперь снова занимаюсь ядром линукса, и от классов с наследованием бы не отказался, но вполне нормально можно жить и без него, на С, с указателями вместо методов и счетчиками ссылок.
Конечно можно, ведь есть полнота по Тьюрингу, да и вообще Блаб-парадокс. С простынями goto cleanup, вездесущим void*, и прочим ручным трудом.
lpd>И возникающие в процессе работы проблемы С++, тем более современный, не решил бы.
Современный упрощает код, причём местами на порядок.
Здравствуйте, Marty, Вы писали:
M>ЗЫ И да, мне нравится, что язык стал активно развиваться, и то, что код написанный 20 лет назад собирается и работает точно так же, как и раньше
Ну, это неверно, конечно. уже довольно часто встречается слово deprecated.
Здравствуйте, Videoman, Вы писали:
V>Как средства решения могут появиться раньше самой задачи.
Почему раньше? Шаблоны появились в ответ на желание сделать код максимально независимым от типа. Несколько десятков лет назад, в ответ на желание сделать код независимым от размера машинного слова, появилась операция sizeof. Точно так же, одновременно с появлением шаблонов или вскорости, обязаны были появиться и предикаты свойств типов/объектов.
V>Мой ответ — скорее всего раньше софт не был таким большим и сложным.
Сложным — был (те же самые промышленные 3D-дизайнеры, которые начали делать еще в 80-х). Настолько большим — не был, тогда еще на набрало такие обороты включение универсальных библиотек, в результате чего, вместо ожидаемого повторного использования кода, происходит его многократное дублирование.
V>Ты же сам критикуешь сложность современного С++, а с таким подходом вообще ахренеешь понимать что в итоге вызывается должно.
Тогда те же претензии должны быть и к const/volatile, которые тоже участвуют в выборе перегрузок.
V>После такого просто глядя на код ты не будешь понимать что вызывается
А для этого, безотносительно к правилам, нужна выдача компилятора о результатах его работы. Как ассемблерный листинг, только на уровне C++.
V>Поверь эти правила быстро станут не проще того кода на шаблонах который тебе не нравится
Да их достаточно самых простейших — "выбирать ближайший подходящий тип", "выбирать наиболее общий тип", ну и критерии подходящести — по размеру, набору операций и т.п.
V>ведь будут тут ныть на форуме: чего это дебажный код работает так медленно, невозможно отлаживаться. Кто-то тут ныл уже, не помню
Ну я ныл о том, что MS VC++ не позволяет мне свободно переключаться между режимами оптимизации хотя бы на уровне функций, не говоря уже об их фрагментах.
V>Если я работаю только с С++ и мне нужны быстрые исключения, то я их выбираю.
Быстрые — это которые? Я глубоко не копал, но, насколько мне известно, в винде плюсовые исключения всегда реализуются через системный SEH.
V>Ну С-то как-то с этим всем работает без исключений.
В MS VC есть __try/__except — то самое SEH, механизм технически не отличается от плюсовых исключений.
V>если ты так близко с железу работаешь, то используй средства OC и скорее всего ты уже и сами исключения в таком случае не будешь использовать.
Я и использую SEH, когда нужно ловить возможные ошибки адресации, или когда функции ядра сами возбуждают системные исключения. А исключений C++ я до сих пор избегаю, но у меня пока сложность не такая, чтоб без них стало прям тяжело.
Здравствуйте, lpd, Вы писали:
lpd>Теперь снова занимаюсь ядром линукса, и от классов с наследованием бы не отказался
В ядре еще неплохо помогли бы атрибуты объектов/функций, наследуемые по цепочке использования. Например, есть некий общий ресурс ядра (список процессов, выделенных страниц памяти и т.п.), который нельзя захватывать в специальных режимах (при обработке прерывания, при выполнении callback'а и т.п.). Вешаем на функцию его захвата атрибут A, на функции вызова обработчиков прерываний — атрибут B, и вводим правило, что атрибуты A и B несовместимы. Тогда любая функция, явно вызванная (непосредственно или опосредованно) из обработчика прерывания, не сможет явно же вызвать функцию захвата ресурса.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, lpd, Вы писали:
EP>Ты путаешь мягкое с тёплым, одно другому не мешает, не противоречит, и не исключает. EP>В том числе и в графике:
ffmpeg/libavcodec написаны на С с редкими вставками ассемблеров, без шаблонов.
А в твоем видео вроде как классический С++ с простыми шаблонами, некоторую пользу которых для контейнеров я не отрицаю.
Оптимизация алгоритма может дать выигрыш быстродействия во много раз. Есть опыт, насколько современный С++ ускорял код по сравнению с классическим?
lpd>>И возникающие в процессе работы проблемы С++, тем более современный, не решил бы.
EP>Современный упрощает код, причём местами на порядок.
Это шутка такая? По-моему современный С++ не проще японского языка, и не сильно для меня полезнее.
Я вообще не особенно честно говоря в курсе, что такого можно сделать на современных шаблонах, чего нельзя сделать на полиморфизме и RTTI? Или вопрос только в быстродействии? Если последнее, то оптимизировать нужно только отдельные участки программы, и сделать это вполне можно без шаблонов и мув-семанитки, вручную. Я бы не стал городить лес из скобочек и двойных амперсандов, но похоже что это вопрос вкуса.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Оптимизация алгоритма может дать выигрыш быстродействия во много раз.
И? В чём поинт-то? Типа "давайте не будем использовать современный C++, а будем писать на C или на старом лампово C++, потому что мы крутые перцы и мы-то оптимизируем алгоритмы, а те кто используют современный C++ этого не делают, и думают что rvalues спасут их медленные алгоритмы"?
lpd>Есть опыт, насколько современный С++ ускорял код по сравнению с классическим?
Странный вопрос.
1. Я могу написать на C++98 такой же быстрый и такой же обобщённый код как и на современном, но этого кода местами будет намного больше. Этот код будет намного сложее и менее понятным.
2. Точно также как же как и на C я смогу написать код таким же быстрым как и на современном C++, только этого кода будет больше в разы, а то и на порядки. Воороужившись кодогенератором, я смогу его даже сделать обобщённым.
3. Я могу написать на Java код близкий по производительности к C++, только этого кода будет даже больше чем на C, и я даже не рискнул бы делать это вручную, а например бы просто генерировал бы его из современного C++, точно также как и Emscripten генерирует быстрый (насколько это возможно) JavaScript из C++, который даже обгоняет C#
.
lpd>>>И возникающие в процессе работы проблемы С++, тем более современный, не решил бы.
EP>>Современный упрощает код, причём местами на порядок. lpd>Это шутка такая? По-моему современный С++ не проще японского языка, и не сильно для меня полезнее.
Нет конечно.
Я уже выше приводил пример с result_of протоколом — десятки строк достаточно специфичной писанины заменяются одним ключивым словом.
Или другой пример if constexpr — во многих местах заменяет эзотерический enable_if, делая код лаконичным И понятным.
lpd>Я вообще не особенно честно говоря в курсе, что такого можно сделать на современных шаблонах, чего нельзя сделать на полиморфизме и RTTI? Или вопрос только в быстродействии?
Вопрос в объёме кода, колличество строчек. Вопрос в читабельности кода.
lpd>Если последнее, то оптимизировать нужно только отдельные участки программы, и сделать это вполне можно без шаблонов и мув-семанитки, вручную.
Конечно можно, именно это и называется blub paradox.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, lpd, Вы писали:
lpd>>Оптимизация алгоритма может дать выигрыш быстродействия во много раз.
EP>И? В чём поинт-то?
Поинт в том, что фичи современного С++ в плане быстродействия — это во многих случаях микрооптимизации, по сравнению с алгоритмом.
А так большинство пишут код на Java/C#, который судя по бенчмаркам в 3 раза медленнее C/C++, и у них быстродействие упирается в сеть, в базу данных, и это все решается горизонтальным масштабированием.
lpd>>Если последнее, то оптимизировать нужно только отдельные участки программы, и сделать это вполне можно без шаблонов и мув-семанитки, вручную.
EP>Конечно можно, именно это и называется blub paradox.
Ну языков программирования много — просто C/C++ давно самые популярные и хайповые. Появись эти новые фичи в каком-нибудь редком языке, он не стал бы мейнстримовым. Я считаю язык программирования с его тонкостями не главным в разработке софта, по сравению с алгоритмом и архитектурой, и не слежу за новинками, да и другие интересы есть.
Но говорить что C++17 лучше, чем C++03 — это вкусовщина.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>>>Оптимизация алгоритма может дать выигрыш быстродействия во много раз. EP>>И? В чём поинт-то? lpd>Поинт в том, что фичи современного С++ в плане быстродействия — это во многих случаях микрооптимизации, по сравнению с алгоритмом.
Ты придумал какие-то тезисы, и сам с ними споришь игнорируя ответы. Вопрос не в сыром быстродействии, ибо оно доступно даже на C.
А в быстродейтсвии на колличество строк — чем новее C++, тем выше этот показатель.
То есть при одинаковом колличестве строк — современный C++ будет быстрее, либо таким же быстрым но при меньше колличестве строк.
lpd>А так большинство пишут код на Java/C#, который судя по бенчмаркам в 3 раза медленнее C/C++, и у них быстродействие упирается в сеть, в базу данных, и это все решается горизонтальным масштабированием.
Задачи и области разные бывают, вот уже надцать лет не работаю с базами данных, за исключением очень рекдих единичных эпизодов.
lpd>Я считаю язык программирования с его тонкостями не главным в разработке софта, по сравению с алгоритмом и архитектурой, и не слежу за новинками, да и другие интересы есть.
Опять двадцать пять. Кто тебе сказал что те кто используют современный C++ обязательно используют плохие алгоримты и проектируют плохую архитектуру?
lpd>Но говорить что C++17 лучше, чем C++03 — это вкусовщина.
Есть объективные показатели — напирмер колличество строк. Но да, кончено меньший объём кода это дело вкуса
Здравствуйте, Evgeny.Panasyuk, Вы писали:
lpd>>Но говорить что C++17 лучше, чем C++03 — это вкусовщина.
EP>Есть объективные показатели — напирмер колличество строк. Но да, кончено меньший объём кода это дело вкуса
Просто пишите весь код в одну строку.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)