Просмотр сообщений
|
Страниц: 1 2 [3] 4 5 ... 217
|
31
|
Программирование / С/C++ / Re: чтение и запись битовых структур данных
|
: Апрель 27, 2021, 12:49
|
Писать в одно поле юниона, а читать из другово (в моих примерах) законно в любом языке. То, о чем говориться по вашей ссылке к моему случаю не имеет отношения.
Нет, не законно=) Это опять возвращает нас к разговору о reinterpret_cast и type punning. Единственный законный способ сделать type punning в современном с++ - это memcpy. В с++20 добавят bit_cast который сейчас можно написать самому через memcpytemplate <class To, class From> typename std::enable_if_t< sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>, To> // constexpr support needs compiler magic bit_cast(const From& src) noexcept { static_assert(std::is_trivially_constructible_v<To>, "This implementation additionally requires destination type to be trivially constructible"); To dst; std::memcpy(&dst, &src, sizeof(To)); return dst; } То есть можно скопировать буфер в структуру через memcpy а вот записать int64_t а потом прочитать из битфилда на него наложеннный - нет. Но да, все известные мне компиляторы это позволяют делать. Но clang-tidy ругается AFAIK
|
|
|
33
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 22, 2021, 11:02
|
So ?
void doWork(const CData &data) { }
template<typename С> void iterateContainer(const С& c) { for (const auto &item: c) { if constexpr (std::is_pointer_v<C::value_type>) doWork(*item); else doWork(item); } }
|
|
|
34
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 22, 2021, 10:55
|
Если в b() генерируется исключение, то в потоке должен остаться результат от a(). А теперь посмотрите что кодогенерит gcc до 7.  Ну да, но это с с++11, на тот момент задача была валидная. Я таки носили простыню про sequencing, пункт 19 https://en.cppreference.com/w/cpp/language/eval_orderНо надо понимать что это поправили только для operator<< и >>, для operator+ порядок по-прежнему не задан.
|
|
|
36
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 21, 2021, 17:00
|
Даже в вашем варианте порядок вызовов четко определен.  Ну вот gcc 4.6 печатает "210", а 10.3 печатает "120" https://godbolt.org/z/Pc9fa4bf9Там в целом были какие-то изменения в с++11, но яхз, поправлено это или "везет" что все новые компиляторы печатают одинаково. Что вначале выполниться boo или f? Улыбающийся
вот только оператор (даже член класса) это функция от двух аргументов foo(f(), g());
не понимаю почему функция-член класса гарантирует что "this" вычисляется первым. где это написано?
|
|
|
37
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 21, 2021, 15:15
|
Нужно было вспомнить, что эта запись сахар для такой  C++ (Qt) std::cout.operator<<( f() ).operator<<( f() ).operator<<( f() ).operator<<( std::endl );
Да, но нет, это не члены класса а свободные функции: C++ (Qt) operator<<(operator<<(operator<<(operator<<( std::cout, f() ), f() ), f() ), std::endl );
и что выполнится вначале - operator<<( std::cout, f() ) или f() - бабка надвое сказала
|
|
|
38
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 21, 2021, 12:03
|
Любая задача имеет по меньшей мере одно решение: снятие самой задачи/проблемы. Здесь оно и будет лучшим - не нужны такие заморочки.
Ну там задачи были разной сложности что позволяло оценить уровень кандидата. Полезно иметь задачу с подвохом ультимативной сложности. Если человек скажет какой-то один из возможных вариантов, то норм (там еще надо продраться сквозь код же), а если про точки следования вспомнит - ваще бох. Правда на моей памяти никто без подсказок не вспомнил, но это и не особо влияло.
|
|
|
39
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 21, 2021, 11:52
|
И как вы предполагали - какой Rand будет вызван первым - левый или правый?
В 2ГИСе мы спрашивали похожую задачку std::cout << f() << f() << f() << std::endl; где f() имеет сайд-эффект (делает i++) никто не решил (я в том числе)
|
|
|
40
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 21, 2021, 11:47
|
Вот этот код дает UB (печатает -1 вместо ожидаемого 0) в обоих случаях (MinGW 8.3, O2):
Да, прикольно, не задумывался о том что placement new можно звать на unrelated типах. Небось тоже где-то прописано что так делать нельзя (кроме char*/void*)
|
|
|
41
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 20, 2021, 16:03
|
Ах, таки вы меня подсекли! Про возможную специализацию внешнего типа я упустил. В данном случае специализации QSet нет, работать будет. Но в общем случае - да, это нужно учитывать.
Там внутри могут быть всякие traits которые для разных типов разные. Но в любом случае, даже если битовое представление одинаковое, это UB. По поводу strict alias rule и оптимизации (привет restrict poiners): А как вы соотнесете это с placement new(), например?
В чем проблема-то? Единственный валидный юзкейз reinterpret_cast между разными типами это каст к массиву байт (или void*) и обратно. Компилятор знает что вон тот char buffer[] потенциально может алиаситься с вот этим указателем и сгенерит менее производительный код. placement new как раз подпадает под это - буфер чаров может алиаситься (и делает это) с указателем на произвольный T. А вот любые другие типы (например int* в double*) алиаситься не могут.
|
|
|
42
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 20, 2021, 15:09
|
Ну или более сложный пример, вы знаете что на вашей платформе sizeof(bool) == sizeof(int8_t) (ну или char). Значит вы можете сделать vector<bool> bools; auto &chars = reinterpret_cast<vector<char>&>(bools);
?
|
|
|
43
|
Программирование / С/C++ / Re: Итераторы
|
: Апрель 20, 2021, 15:04
|
Это UB, в общем случае нельзя делать reinterpret_cast между unrelated типами. https://en.cppreference.com/w/cpp/language/reinterpret_caststd::pair<int, int> and std::pair<const int, int> are not similar. Компилятор предполагает что 2 ссылки/указателя на различные типы не могут ссылаться не одну область памяти (strict alias rule) и строит на этом оптимизации. reinterpret_cast ломает это предположение - если компилятор тупенький и не оптимизирует, то это будет работать, если умный, то сломается. UB.
|
|
|
|
|