- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
// https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/qglobal.h?h=v5.13.1#n1017
#if __cplusplus >= 201703L
// Use C++17 if statement with initializer. User's code ends up in a else so
// scoping of different ifs is not broken
#define Q_FOREACH(variable, container) \
for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
_container_.i != _container_.e; ++_container_.i) \
if (variable = *_container_.i; false) {} else
#else
// Explanation of the control word:
// - it's initialized to 1
// - that means both the inner and outer loops start
// - if there were no breaks, at the end of the inner loop, it's set to 0, which
// causes it to exit (the inner loop is run exactly once)
// - at the end of the outer loop, it's inverted, so it becomes 1 again, allowing
// the outer loop to continue executing
// - if there was a break inside the inner loop, it will exit with control still
// set to 1; in that case, the outer loop will invert it to 0 and will exit too
#define Q_FOREACH(variable, container) \
for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
_container_.control && _container_.i != _container_.e; \
++_container_.i, _container_.control ^= 1) \
for (variable = *_container_.i; _container_.control; _container_.control = 0)
#endif
А можно ли свой foreach сделать через какую-нибудь шаблонопарашу? Или тут, как обычно, нужна гомоиконность?
Нахуя это? Откуда они взяли эти замечательные константы 0.00001f, 0.000000000001, 100000.f, 1000000000000. ? Может надо std::numeric_limits<T>::epsilon использовать?
Так вроде бы type punning в крестах это UB.
https://stackoverflow.com/questions/11373203/
> The confusion is that C explicitly permits type-punning through a union, whereas C++ (c++11) has no such permission.
Какой багор )))
И нахуя они понаделали quint32 quint64 но например не сделали qfloat qdouble? Чем их не устроило uint32_t uint64_t?
Хотя мне и в сишке статик ассёрт + мемсру больше нравится. Короче выглядит, не надо юнион на ровном месте выдумывать. Да и по пирфомансу то на то и выйдет.
Пруф: Даже через память тащить не стало.
От стрикт-алиазинга в GCC отказываться можно через -fno-strict-aliasing или __attribute((__may_alias__))
А хуйня с UB с юнионами в GCC для крестопараши и старой сишки разрешена и так
https://stackoverflow.com/a/25672839
> GNU extensions to standard C++ (and to C90) do explicitly allow type-punning with unions. Other compilers that don't support GNU extensions may also support union type-punning, but it's not part of the base language standard.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Type-punning
> Pay special attention to code like this:
> The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the code above works as expected.
пушо десктрукторы не понятно когда вызывацьт?
Если напишешь -- будет. Может быть там у элементов юниона есть какой-то общий хедер и ты хочешь по нему по-ня-ть тип и правильно всё почистить.
Вот если сделать структуру с хедером, и в ней уже юнион - это другое дело
18. If a standard-layout union contains two or more standard-layout structs that share a common initial sequence,and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.
грубо говоря, если два петуха начинаются на int, то этот int можно читать через любого питуха?
7. A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member.
Совместимый по лейауту с сишной структурой, если интуитивно.
> — has no virtual functions (10.3) and no virtual base classes (10.1),
остальное из нее выводится
А цимес небось в том, что в начале виртуального класса может таится какая-то хуйня типа указателя на vtb или на предка, да?
ну тоесть
реально начинается с инта (плюс минус специфичный для платформы алайн, общий для всех)
а если он виртуально наследует Petuh, то там уже в начале хуууй знает что
З.Ы. Про последний пункт я не помню, если честно, почему так. Вроде чтобы не пересеклись адреса при empty base class optimization.
> If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.
З.Ы. Что-то мне намекает, что в няшной они бы тоже рады убрать. Но уже все юзают.
Кроме того, если у тебя что-то вроде
Так что тут и кресты обосрутся.
А еще они обосрутся если у тебя в функцию просто передаются два указателя на флоат, и ты точно знаешь, что они на разную хуйню указывают. Так что я за __restrict
Так то да... В кресты его тоже пытаются протолкнуть, но пока запутались в сёмантике и отложили.
Знание компилятора о том, что там вот этот юнион пишется через uint32_t ему не помогают
Т.е. в общем-то все популярные крестоконпеляторы по-сишному это трактуют.
З.Ы. Ну просто это сразу ломает копипасту из сишного кода, а конпеляторы не любят её ломать.
Не нарушает ли icc стандарт Си?
А это точно си? Мож там опции от крестов просочились где-то?
В крестах вот убрали, но все юзают, так что компиляторы такую хуйню поддерживают по-факту. И похуй на стандарт.
Ты не знаешь какой там класс сейсас "активный", но думаешь: раз они оба начинается с ``unit32_t``, то считаю-ка я первые 4 байта, и будет заебись.
В сишке так и будет.
А в C++ там в начале класса указатель на виртуальное говно
Во-вторых, виртуальное говно можно по отрицательным смещениям размещать, а данные пусть сразу начинается. Например, размер виртуального говна можно размещать по смещению class_ptr[-4] как 32-битное число, а по еще более отрицательным будет само виртуальное говно.
Ебать ты буквоед, ну замени класс на структуру же.
>Во-вторых, виртуальное говно можно по отрицательным смещениям размещать
А как будет работать какое-нить memcpy?
А зачем копировать такую хрень через memcpy? Если надо конкретно переменные из класса, работать это будет без проблем. А для всякой отрицательной хуйни можно особую функцию сделать.
Я думал, если объект trivilaly copyable (ну то есть без сложных конструкторов всяких в себе и полях) то его можно memcpyить куда-то..
Виртуальное говно очень редко trivially copyable, как мне кажется.
З.Ы. Или вообще никогда...
>редко
тоже так кажется (если там виртуальное, то туда уже оопидор пролез, и значит там конструкторы строго следят за инвариантом класса итд)
Тем не менее, если стандарт это уже разрешил, то хранить что-то "перед" указателем будет тяжеловато
>З.Ы. Или вообще никогда...
абстрактная фабрика, или стратегия с несколькими методами (если один, то наверное лучше лямбдой)
тока в них копировать нечего, лол
Так что этот кейс можно не рассматривать. Минусы в мемсру никогда не попадут.
``std::is_trivially_copyable``
Всё равно меня пугает идея джейцифирек, тебя нет?
>Base b = child меняет vtb
ну да, при копировании нужно не просто байтики скопировать, а указатель с ребенка перевести на родителя, не подумал
И там
par1_data
par2_data
child_data
а потом ты static_cast указателя Child* в Par2*, и стрелочка перемещается в par2_data, а "par1_data" оказывается "в минусе"
Или даже тупо передаешь Child в функцию, ожидающую Parent2&
Там сразу qкватернионы идут.
Пора уходить в строительную деятельность. Там хоть настоящий креатив можно применить, при оштукатуривании стен и прочих прокладках сантехники. А не вот это вот всё.
(да, я про NPM)
https://en.cppreference.com/w/cpp/language/range-for
Но для крестоценителей всегда есть такая жемчужина, как
https://www.boost.org/doc/libs/1_76_0/boost/foreach.hpp
> https://www.boost.org/doc/libs/1_76_0/boost/foreach.hpp
Копролит, скорее.
BOOST_FOREACH разъебал в одну калитку этот ламерский Q_FOREACH
написать макрос на 500 строк могут не только лишь все
про репродуктивные забыли