не содержали UB. S>>Вообще-то это не решение, а непонимание автором вопроса собственных желаний и возможностей ЯП. Причем здесь вопрос даже не C++, а в том, что у человека проблемы с пониманием принципов работы статической типизации.
BFE>Зато намерения автора прозрачны: иметь прямой и простой доступ к байтовому представлению базовых типов в памяти.
Простите, но не в изначальной формулировке:
к примеру:
auto val = GetValue(value);
и соответственно если value.type = Type::int_ val будет типа int и тд. ?
В C++ тип val должен быть определен в compile-time, даже если он помечен в коде как auto. Т.е. если в value лежит int, то и val должен быть int, но в compile-time мы этого не знаем.
Какие-то подозрения могли бы быть, если бы код в примере выглядел как-то так:
auto val = GetValue<int>(value);
Но таких намеков нет.
Re[9]: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, пффф, Вы писали:
S>>Вы считаете, что между этими вариантами будет какое-то принципиальное различие в производительности?
П>А где самый напрашивающийся вариант через std::copy_if?
Наверное там же, где и ваша внимательность, но это не точно.
Re[3]: Позиция C++ среди популярных ЯП и его изучение
ЕМ>Ну вот тот же MS добавил в свой VC++ расширения в виде некоторого количества предикатов (__has_assign, __is_class, __is_convertible_to и т.п.), квалификатор __interface для определения интерфейсного (чисто абстрактного) класса, __if_exists/__if_not_exists для условной компиляции по наличию/отсутствию определения, __forceinline для принудительной вставки функции, и так далее. Ничего из этого в стандартный язык не пошло. Свойства типов — по-прежнему только магия, интерфейсный класс извольте описывать ручками с "= 0" при каждой функции, для принудительного inline каждый копилятор тащит свои атрибуты, нормальной условной компиляции так и нет — выкручивайтесь магией.
не содержали UB. S>>>Вообще-то это не решение, а непонимание автором вопроса собственных желаний и возможностей ЯП. Причем здесь вопрос даже не C++, а в том, что у человека проблемы с пониманием принципов работы статической типизации. BFE>>Зато намерения автора прозрачны: иметь прямой и простой доступ к байтовому представлению базовых типов в памяти. S>Простите, но не в изначальной формулировке:
Я, таки, разделяю вопрос автора и его намерения. А намеревается он именно, что сериализовать бинарные данные...
S>
S>к примеру:
S>
S>auto val = GetValue(value);
S>
S>и соответственно если value.type = Type::int_ val будет типа int и тд. ?
S>В C++ тип val должен быть определен в compile-time, даже если он помечен в коде как auto. Т.е. если в value лежит int, то и val должен быть int, но в compile-time мы этого не знаем.
Да, но есть обходные пути: val может быть промежуточного типа с операторами преобразования типа в тип цели...
Но я вообще не об этом, а о доступе к данным одного типа, как к данным другого типа. По стандарту это настолько мутная история, что я так и не понял, когда и что во что можно преобразовывать, а что нельзя.
Здравствуйте, B0FEE664, Вы писали:
S>>Простите, но не в изначальной формулировке: BFE>Я, таки, разделяю вопрос автора и его намерения. А намеревается он именно, что сериализовать бинарные данные...
Скорее уж десериализовать.
Но тут все точно как в жизненной мудрости, "без ТЗ и результат ХЗ". Форумчане не должны угадывать желания автора вопроса, о чем спросил, на то и ответили.
BFE>Да,
Ну вот вопрос и закрыт.
BFE>но есть обходные пути: val может быть промежуточного типа с операторами преобразования типа в тип цели...
Это не обходные пути, это решение другой задачи, а именно: как сделать тип, который может внутри себя держать значения нескольких других типов (т.е. очередная итерация вокруг union/variant). Но задача принципиально другая, т.к. в ран-тайме у вас все равно val будет не int, не double, а что-то, что может их внутри себя инкапсулировать и как-то давать доступ.
BFE>Но я вообще не об этом, а о доступе к данным одного типа, как к данным другого типа. По стандарту это настолько мутная история, что я так и не понял, когда и что во что можно преобразовывать, а что нельзя.
Так ведь с каждым стандартом с этим все проще и проще становится.
Сперва добавили alignas и alignof. Так что можно делать массивы для хранения байтовых представлений с правильным выравниванием.
Теперь вот добрались до std::start_lifetime_as, что как раз таки избавляет от UB связанного с тем, что компилятор ни сном ни духом про начало жизни объекта некоторого типа T внутри произвольного байтового буфера.
Поэтому с этой стороны в качестве претензий можно предъявить разве что нехилое такое опоздание с внедрением этого в стандарт.
Re: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ> Но умеющий в ассемблер, как правило, достаточно хорошо понимает, каким образом к нему сводятся все остальные языки. Когда-то и средний программист на C++, даже не зная ассемблера, неплохо понимал "кухню" вычислительной системы, и хотя бы примерно представлял, как в итоге будет организовано "на железе" выполнение программы, обработка данных, взаимодействие и т.п.
Есть известный пример как знание организации кода "на железе" привело к пессимизации выполнения программ на С++. А именно история стандартизации std::vector, которая привела к замедлению работы с этим контейнером. Изначально в стандарте не было требования о том, что данные вектора должны лежать непрерывным куском в памяти. Теоретически это существенно повышает скорость работы, так как добавление новых элементов не требует копирования/переноса всех элементов массива. Однако именно понимание "кухни" вычислительной системы и того, как в итоге будет организовано "на железе" выполнение программы, привело к стандартизации vector'а как непрерывного куска в памяти, а быструю реализацию вектора составленного из других векторов, так никто и не имплементировал, насколько я знаю. Теоретически мы могли бы иметь std::vector обгоняющий std::deque на всех операциях, но — нет.
Это не единственный пример того, когда знание организации кода выполнения приводит к нелогичному развитию требований стандарта.
И каждый день — без права на ошибку...
Re[2]: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, B0FEE664, Вы писали:
BFE>Есть известный пример как знание организации кода "на железе" привело к пессимизации выполнения программ на С++. А именно история стандартизации std::vector, которая привела к замедлению работы с этим контейнером. Изначально в стандарте не было требования о том, что данные вектора должны лежать непрерывным куском в памяти. Теоретически это существенно повышает скорость работы, так как добавление новых элементов не требует копирования/переноса всех элементов массива. Однако именно понимание "кухни" вычислительной системы и того, как в итоге будет организовано "на железе" выполнение программы, привело к стандартизации vector'а как непрерывного куска в памяти, а быструю реализацию вектора составленного из других векторов, так никто и не имплементировал, насколько я знаю. Теоретически мы могли бы иметь std::vector обгоняющий std::deque на всех операциях, но — нет.
А можно ссылочку на первоисточник? Звучит уж как-то невероятно.
ЕМНИП, это касательно std::string C++98 допускал трактовки, позволяющие и COW-реализации, и реализации на базе ROPE.
И только в C++11 стандарт был переформулирован так, чтобы std::string::data возвращал указатель на непрерывный блок памяти.
Re: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Получилось сумбурно. По-хорошему, такие вопросы надо рассматривать, как минимум, в большой статье, но нет ни времени, ни желания ее сочинять — все равно мало кто поймет.
Это общее направление развития индустрии, вполне логичное на мой взгляд, и не остается ничего кроме как с этим смириться.
Отвечаю опять же ссылкой на цитату из книги — "Глубина в Небе", там эта идея отражается в виде профессии "программиста-археолога", который занят именно адаптацией древних программ.
Не написанием чего-то нового, а именно тем что пытается адаптировать и заставить работать то что было написано за столетия до него.
Извиняюсь за отсылку. Вот нашел фрагмент:
– Для этой ситуации есть специальный термин: «зрелая среда программирования».
В общем, когда производительность аппаратного обеспечения выходит на предел, а программисты пишут код уже столетиями, достигается момент,
когда значимого кода больше, чем кто бы то ни было способен осмыслить. Лучшее, что можно сделать в этой ситуации, – изучить общую иерархическую структуру и понять,
как найти нужные инструменты, когда они понадобятся.
Другого выхода как идти в сторону "кубиков" и "кирпичиков" я просто не вижу, объем слишком велик для понимания, и он растет
Для C++ просто не видно другого выхода, кроме как плыть в этом потоке.
Re[3]: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, so5team, Вы писали:
S>А можно ссылочку на первоисточник? Звучит уж как-то невероятно.
На первоисточник чего? На стандарт C++98?
Ну откройте, посмотрите. Там даже std::vector::data() отсутствует.
И каждый день — без права на ошибку...
Re[4]: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, so5team, Вы писали:
S>>>А можно ссылочку на первоисточник? Звучит уж как-то невероятно. BFE>>На первоисточник чего? S>Обсуждений по ужесточению требований к std::vector.
Да я не знаю, где взять такой источник. Да и зачем он вам?
Аргументация того, что я читал, если мне не изменяет память, сводилась к тому, что часто данные из вектора в уже написанных программах передаются в функции C и чтобы не ломать уже существующий код, просто зафиксировали в стандарте существующую практику. Ну, а что было делать? На введённое требование, кстати, никто не жаловался, ну или мне такие жалобы не встречались.
Похожая история произошла с memcpy, но в отличии от вектора, для memcpy изначально было требование на неперекрытие диапазонов. Разумеется все те, кто знал, как оно там в итоге будет организовано "на железе" запросто писали копирование перекрывающихся кусков. Ну и пожалуйста, до сих пор отголоски видны даже здесь
Здравствуйте, B0FEE664, Вы писали:
S>>>>А можно ссылочку на первоисточник? Звучит уж как-то невероятно. BFE>>>На первоисточник чего? S>>Обсуждений по ужесточению требований к std::vector.
BFE>Да я не знаю, где взять такой источник.
Жаль.
BFE>Да и зачем он вам?
Да просто интересно. Насколько я помню, сам Страуструп после появления std::vector говорил, что если вам нужен динамический массив, то вместо `malloc` и `new[]` следует использовать именно std::vector, мол получаете тот же самый непрерывный массив значений, а накладных расходов всего-то плюс два std::size_t.
BFE>Аргументация того, что я читал, если мне не изменяет память, сводилась к тому, что часто данные из вектора в уже написанных программах передаются в функции C и чтобы не ломать уже существующий код, просто зафиксировали в стандарте существующую практику. Ну, а что было делать? На введённое требование, кстати, никто не жаловался, ну или мне такие жалобы не встречались.
А вот я такого по отношению к std::vector не помню.
Re: Позиция C++ среди популярных ЯП и его изучение
ЕМ>[q]Автору этих строк представляется очевидным, что язык Си (чистый Си) смог стать тем, чем он стал, и занять его нынешнюю нишу благодаря двум своим очевидным свойствам: во-первых, жесткой и очевидной границе между самим языком и его библиотекой, сколь бы "стандартной" она ни была, и, во-вторых, достижимости "zero runtime", т.е. возможности использования созданных компилятором объектных модулей без поддержки со стороны поставляемых с компилятором библиотек. В отсутствие любого из этих свойств язык программирования оказывается неприменим для программирования на "голом железе" (т.е. для ядер операционных систем и для прошивок микроконтроллеров) и, как следствие, не может претендовать на универсальность. Тем удивительнее, сколь упорно создатели "стандартов" пытаются изничтожить оба этих свойства, причем как в Си++, так и в чистом Си".
А как же libc? Или эту библиотеку можно сделать опциональной?
Кодом людям нужно помогать!
Re[2]: Позиция C++ среди популярных ЯП и его изучение
Здравствуйте, Sharov, Вы писали:
S>А как же libc? Или эту библиотеку можно сделать опциональной?
Конечно. Любой адекватный компилятор создает ссылки к libc только при реальной необходимости.
Например, по умолчанию точка входа в исполняемый модуль берется из libc, и создает стандартную среду для main (разбирает параметры командной строки, добывает набор переменных среды, инициализирует CRT, вызывает конструкторы статических объектов и т.п.). Если скомпилировать произвольную функцию без этих зависимостей и указать ее линкеру в качестве точки входа, из libc не добавляется ничего, и получается минимально возможный исполняемый модуль.
Для каких-то функций libc/CRT можно создать свои "пустышки". Например, в некоторых реализациях, особенно в отладочных сборках, многие функции libc, обнаружив недопустимые параметры на входе, вызывают диагностические средства из той же libc. Выяснив, что именно вызывается, можно вместо этих диагностических функций определить свои, "экранируя" стандартные.