S>Попробуйте объяснить какой из этих вариантов наиболее удобен и почему.
Для простейших случаев второй, вестимо.
Для нескольких requires подходит только последний.
Насчёт того, что с синтаксисом что-то надо делать — согласен.
Второй вариант уже что-то делает с синтаксисом, но он работает только для аргументов-типов, а хотелось бы еще с константами времени компиляции.
Или даже сделать typename опциональным-дефолтным, тогда:
void fn<int c, T3<int, T4> >(auto arg1, auto arg2) {}
(хотя, здесь такие же опасения, как для var/let — требуется ли явное указание, что вводится новая сущность, чтобы избежать ошибок переприсвоения уже имеющейся переменной, в данном случае — переменной типа, которая внезапно может оказаться уже определённым символом в данном контексте, таким же int, например)
При наличи конструкций ->decltype() предварительный синтаксис template<> уже не столь нужен, т.к. есть альтернативный способ вывода типа результата шаблонных ф-ий.
S>>Попробуйте объяснить какой из этих вариантов наиболее удобен и почему.
V>Для простейших случаев второй, вестимо.
V>Для нескольких requires подходит только последний.
Так что сам по себе синтаксис -- это одна проблема.
Вторая -- это то, что если слишком много способов сделать одно и тоже. Про некоторые можно тупо забыть.
Здравствуйте, Alekzander, Вы писали: A>Хотя, конечно, как идея *компилируемая* виртуальная машина, свободная, собираемая для каждого проекта — я так себе представляю идеальную виртуальную машину С++ — это неплохая идея!
Эмм, вы всё ещё не про Low Level Virtual Machine?
Вот в ней всё как раз грамотно — UB вносится только там, где вы намеренно хотите получить UB (сделано по особой просьбе компиляторов С++).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, FR, Вы писали: FR>UB же от оптимизации сильно зависит, вряд-ли получится.
UB — это классический мат в два хода.
Изначально, авторы плюсов боялись спугнуть производителей хардвара.
Типа, "вдруг мы потребуем, чтобы byte(127) + 1 равнялось -128, а кто-то выпустит процессор, где используется обратный код вместо дополнительного?
Тогда компилятор под этот процессор будет порождать очень неэффективный код, потому что дефолтное поведение в виде -127 нас не устроит."
В итоге — "давайте объявим целое переполнение UB, тогда каждый компилятор реализует его самым уместным на его платформе образом".
Офигенно, чо. И волки сыты, и овцы целы. А если погромизд пишет программу, рассчитывая на какое-то конкретное поведение при переполнении, то сам дурак.
Вот, например:
Что тут может пойти не так? Во всех мыслимых процессорах, включая экзотический обратный код, инкремент максимального значения меняет знак, так что сравнение должно сработать.
А дальше компилятор делает второй ход: а раз в стандарте написано, что переполнение — это UB, то я могу делать что угодно, без оглядки на аппаратуру.
И, например, заменяю всю эту функцию на return false, и попутно встраиваю её во все места использования, выбрасывая все ветки кода, управляемые этим условием. Даже при компиляции под конкретный интел, который ведёт себя вполне себе defined образом.
Да, программа работает не так, как ожидал программист, но зато очень быстро. PROFIT!
Как по мне, так это очень похоже на каких-нибудь хитрожопых юристов, которые находят лазейку в законах и доят государство.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
A>>Хотя, конечно, как идея *компилируемая* виртуальная машина, свободная, собираемая для каждого проекта — я так себе представляю идеальную виртуальную машину С++ — это неплохая идея! S>Эмм, вы всё ещё не про Low Level Virtual Machine? S>Вот в ней всё как раз грамотно — UB вносится только там, где вы намеренно хотите получить UB (сделано по особой просьбе компиляторов С++).
"Виртуальная машина" — очень многозначное понятие. Даже в Си есть виртуальная машина, о чём многие сишники не догадываются.
Не знаю, что имеют в виду мои собеседники, а я говорю про "как CLR/JVM". С поправкой на то, что обе — как я это называю, "инфраструктурные ВМ", т.е. откуда-то берутся, содержат джиттер, обеспечивают централизованное хранилище компонентов и т.п., а в C++ это, с моей точки зрения, был бы дурдом похлеще нынешнего. В C++, с моей точки зрения, есть смысл если и делать что-то подобное, то как-то бутстраппиться (в мюнхгаузеновском смысле). Например, на этапе сборки компилировать ВМ в бинари, а код приложения — в байт-код, и запаковывать вместе.
Почему я считаю именно так, могу пояснить отдельно.
S>Что тут может пойти не так? Во всех мыслимых процессорах, включая экзотический обратный код, инкремент максимального значения меняет знак, так что сравнение должно сработать.
S>А дальше компилятор делает второй ход: а раз в стандарте написано, что переполнение — это UB, то я могу делать что угодно, без оглядки на аппаратуру. S>И, например, заменяю всю эту функцию на return false, и попутно встраиваю её во все места использования, выбрасывая все ветки кода, управляемые этим условием. Даже при компиляции под конкретный интел, который ведёт себя вполне себе defined образом. S>Да, программа работает не так, как ожидал программист, но зато очень быстро. PROFIT! S>Как по мне, так это очень похоже на каких-нибудь хитрожопых юристов, которые находят лазейку в законах и доят государство.
Тут встретились две беды: дураки и другие дураки.
Одни ввели UB как концепцию, чего делать было нельзя ни в коем разе. Если и есть в нашей индустрии "ошибка на миллиард долларов", то это не null pointers, а как раз легитимизация UB.
А другие (как и во многих примерах в этом обсуждении) решили, что кроме системных сценариев никаких других нет, даёшь скорость любой ценой. (Хотя люди, которые пишут реальные операционные системы, очень негодуют на оптимизирующие компиляторы, наш главный анфан-терибль уже и на..й их слал открытым текстом). И совершенно игнорируют тот факт, что если люди написали return (value+1) < value, значит, наверное, хотели, чтобы сгенерировался соответствующий код (ну, не от делать же нечего пишутся такие вещи). Впрочем, они часто переводят стрелки, говоря, что с тем шаблонным говном, из которого стандартная библиотека состоит чуть менее, чем полностью, без агрессивной оптимизации всё просто помрёт. Но я думаю, тут они привирают, потому что некоторые оптимизации, как я слышал, отключить просто нельзя. То есть, сравнение с хитрожопыми юристами, разводящими на бабло, явно льстит этим кадрам, у которых, по-моему, просто синдром вахтёра.
Здравствуйте, Alekzander, Вы писали:
A>Не знаю, что имеют в виду мои собеседники, а я говорю про "как CLR/JVM". С поправкой на то, что обе — как я это называю, "инфраструктурные ВМ", т.е. откуда-то берутся, содержат джиттер, обеспечивают централизованное хранилище компонентов и т.п., а в C++ это, с моей точки зрения, был бы дурдом похлеще нынешнего. В C++, с моей точки зрения, есть смысл если и делать что-то подобное, то как-то бутстраппиться (в мюнхгаузеновском смысле). Например, на этапе сборки компилировать ВМ в бинари, а код приложения — в байт-код, и запаковывать вместе.
А, собственно, накуа? LLVM — и есть такая "виртуальная машина". Можно "паковать в бинарь" LLVM-представление (которое сейчас генерируют чуть менее, чем все компиляторы C/C++), и JIT/AOT его на целевой платформе непосредственно перед употреблением.
Ну, а если целевая платформа известна заранее, то, собственно, происходит то, что происходит в clang — LLVM IR отдаётся в бэкенд, который его немедленно компилирует в бинарь.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
A>>Не знаю, что имеют в виду мои собеседники, а я говорю про "как CLR/JVM". С поправкой на то, что обе — как я это называю, "инфраструктурные ВМ", т.е. откуда-то берутся, содержат джиттер, обеспечивают централизованное хранилище компонентов и т.п., а в C++ это, с моей точки зрения, был бы дурдом похлеще нынешнего. В C++, с моей точки зрения, есть смысл если и делать что-то подобное, то как-то бутстраппиться (в мюнхгаузеновском смысле). Например, на этапе сборки компилировать ВМ в бинари, а код приложения — в байт-код, и запаковывать вместе. S>А, собственно, накуа? LLVM — и есть такая "виртуальная машина". Можно "паковать в бинарь" LLVM-представление (которое сейчас генерируют чуть менее, чем все компиляторы C/C++), и JIT/AOT его на целевой платформе непосредственно перед употреблением. S>Ну, а если целевая платформа известна заранее, то, собственно, происходит то, что происходит в clang — LLVM IR отдаётся в бэкенд, который его немедленно компилирует в бинарь.
Я мало что знаю про LLVM. Да и про то, что под капотом у дотнета, ненамного больше. И не стесняюсь в этом признаться, потому что специализируюсь в других вещах, а ковыряться в байткодах и всяких AOT мне неинтересно. Прошу считать это дисклеймером.
Если взять, например, исключения, мне очень нравится, как работа с ними построена в дотнете. Они стандартизированы, унифицированы и поддержаны на уровне CLR (по крайней мере, я видел в IL инструкцию throw). В результате, можно написать программу, которая только выкидывает исключения, вообще их не ловя, а ловить их будет отладочная среда. Ловить, выводить в лог, и заставлять программу хромать дальше. Вот поэтому я люблю исключения в дотнете, это действительно хороший и надёжный механизм обработки ошибок. А в C++ исключения, если их неправильно приготовить, могут стать самостоятельным источником ошибок.
Что для этого предусмотрено в LLVM, и предусмотрено ли хоть что-то? Это вообще продукт (в этом смысле) или набор фарша "сделай сам"? Я спрашиваю без фиги в кармане, потому что, ещё раз, не использовал нигде и толком не разбирался. Но почитав про него, мне кажется, там нет ничего из того, что я бы оценил как юзер. В частности, не вижу среди его типов никакого root Object, никакого std::exception, а вижу только поддержку UDT-структур. Это, я так понимаю, означает для получения сопоставимого удобства по обработке ошибок необходимость "аккуратно обработать напильником".
Здравствуйте, CreatorCray, Вы писали:
_>>Вот как раз виртуальная машина в C++ не помешала бы. CC>Нафиг, нафиг!
В виртуально машине можно отслеживать изменение памяти, кто где и сколько, хранить мета информацию о участках памяти и ветках выполняемого кода, вызывать разные реализации одних и тех же функций и сравнивать результаты их выполнения, выявляя отклонения, следить за инвариантами, собирать статистику, ставить хуки и еще много больных сценариев. Короче сплошной "позитив" для отладки и анализа кода.
В качестве языков для софта уже есть C#/Java
Библиотеки пишут на чем попало, но в основном C.
Датамайнеры и прочие автоматизаторы гоняют Python
Для нишевых применений — куча экзотики вызывающей вывих мозга одним видом.
А это чудо с вывернутым синтаксисом — в одну кучу с растом, пусть грызут друг-друга и людям жить не мешают.
Попытки впихнуть людям в глотку паскале-подобный синтаксис под видом новации уже достали. Пусть им дальше студентов мучают и вумные научные работы пишут.
Здравствуйте, Alekzander, Вы писали:
A>Хотя люди, которые пишут реальные операционные системы, очень негодуют на оптимизирующие компиляторы
Чушь. Мы негодуем на криворукие компиляторы (гнусь и кланг), которые считают что они умнее автора кода и молча выкидывают ветки, вместо того, чтоб сказать что вот тут что то странное.
A> наш главный анфан-терибль уже и на..й их слал открытым текстом.
Это пЫнгвин который? Пусть бесится, он уже показал не раз что он банально тупой.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, kov_serg, Вы писали:
_>В виртуально машине можно отслеживать изменение памяти, кто где и сколько
А теперь расскажи во сколько раз это замедлит выполнение всего кода.
_> хранить мета информацию о участках памяти и ветках выполняемого кода
Нафига?
_> вызывать разные реализации одних и тех же функций и сравнивать результаты их выполнения
Нафига для этого VM?
Профилирование под виртуалкой похерит измеряемые значения, намеряешь совсем не то, что будет без виртуалки.
_> выявляя отклонения, следить за инвариантами, собирать статистику, ставить хуки и еще много больных сценариев.
Это всё называется инструментация
_> Короче сплошной "позитив" для отладки и анализа кода.
Зачем для этого VM?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали: A>>Хотя люди, которые пишут реальные операционные системы, очень негодуют на оптимизирующие компиляторы CC>Чушь. Мы негодуем на криворукие компиляторы (гнусь и кланг), которые считают что они умнее автора кода и молча выкидывают ветки, вместо того, чтоб сказать что вот тут что то странное.
Хм. Я надеюсь, вы в курсе, что примерно все компиляторы делают именно так? Включая компиляторы от интела, MS, Nvidia и так далее?
Я тут потратил полчаса на gotbolt.org, и так и не смог найти компилятор, который бы не демонстрировал указанное поведение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Хм. Я надеюсь, вы в курсе, что примерно все компиляторы делают именно так?
Я в курсе что далеко не все компиляторы делают так.
А те, кто пытается так делать, получают звездюлей и переделывают.
В выдаче звездюлей я не так давно участвовал лично, когда кому то пришла в голову замечательная идея улучшить clang.
S>Я тут потратил полчаса на gotbolt.org, и так и не смог найти компилятор, который бы не демонстрировал указанное поведение.
Какое именно?
А то я интелом пользуюсь давно и с удовольствием и никаких проблем с ним не имею.
Самый вменяемый из всех, кого я когда либо пользовал.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Nuzhny, Вы писали:
S>>Зачем вам первый вызов size()?
N>Не смог придумать пример поумнее, когда бы у меня вызов size() завис в воздухе. Такое использование видел в старых проектах, чтобы лишний раз функцию не вызывать.
Кстати о птичках. Пример, что называется, с пылу, с жару.
Делал вчера демонстрационный пример, чтобы рассказать практикантам азы многопоточности. Написал вот такой фрагмент:
Тупо опечатался в выражении, но компилятор выдал предупреждение, что у operator+ для std::string возвращаемое значение nodiscard. И ошибка сразу стала очевидна: нужно было commonData += "A". Опечатка дурацкая, хз как допущенная, но незамеченная мной, однако замеченная компилятором. Что избавило от последующего поиска причины неожиданного поведения.
Здравствуйте, CreatorCray, Вы писали: CC>Я в курсе что далеко не все компиляторы делают так.
Ну, тогда покажите же мне тот волшебный компилятор, который так не делает.
CC>А те, кто пытается так делать, получают звездюлей и переделывают.
Надежды юношей питают. CC>В выдаче звездюлей я не так давно участвовал лично, когда кому то пришла в голову замечательная идея улучшить clang. На всех звездюлей не напасёшься.
CC>Какое именно?
Я же привёл пример кода. CC>А то я интелом пользуюсь давно и с удовольствием и никаких проблем с ним не имею.
Давайте, я вам покажу, как работает интел: https://godbolt.org/z/jxhxo56bT
Попробуйте найти в бинаре следы "wow".
Можете попробовать поменять флаги компиляции на -O0 и убедиться, что без оптимизаций результат будет категорически другим.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.