Size: a a a

2021 February 10

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
Да не, с кастами то как раз не в порядке, уже дальше пробовать не надо :) Оно так у меня работало давно, а вот десятый gcc нашёл UB и начал странные очень warning'и генерить. Какие то выходы за границы массива по индексу -1 там где массивами даже не пахло. Как раз из за downcast к несуществующей базе.
Без реального кода не могу ничего сказать, если честно. С виду больше похоже на то, что рекурсией задело что-то важное.
источник

MK

Mikhail Kalugin in pro.cxx
Может в компиляторе глюк...
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
Да не, с кастами то как раз не в порядке, уже дальше пробовать не надо :) Оно так у меня работало давно, а вот десятый gcc нашёл UB и начал странные очень warning'и генерить. Какие то выходы за границы массива по индексу -1 там где массивами даже не пахло. Как раз из за downcast к несуществующей базе.
Каст там безопасный только из-за ленивости шаблонов. Когда дело доходит до каста все классы уже определены полностью. Если это поломали - то поломается очень очень много всего.
источник

DS

Dmitry Sokolov in pro.cxx
Mikhail Kalugin
Каст там безопасный только из-за ленивости шаблонов. Когда дело доходит до каста все классы уже определены полностью. Если это поломали - то поломается очень очень много всего.
При чём тут рекурсия, не понимаю. Примерно все три строки кода я и привел. Причем после своих же объяснений понимаю откуда warning :)
Просто проверки, если есть объект с фиксированным адресом, то любая допустимая с его адресом арифметика (выходящая за пределы его sizeof) это доступ к массиву. Вычитание смещения при приведении к Derived как раз эту проверку и возбуждает.
источник
2021 February 11

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
При чём тут рекурсия, не понимаю. Примерно все три строки кода я и привел. Причем после своих же объяснений понимаю откуда warning :)
Просто проверки, если есть объект с фиксированным адресом, то любая допустимая с его адресом арифметика (выходящая за пределы его sizeof) это доступ к массиву. Вычитание смещения при приведении к Derived как раз эту проверку и возбуждает.
В общем, каст легальный и работает. Рекурсию того вида, что я предполагал получить очень сложно (компилятор умный - экземпляр не до конца определенного типа не даст создать, только указатели на него). Что из себя представляет list_member? P.S. А может, я просто слишком долго играл с CRTP (всякие ATL, WTL, самописные фреймворки) и знаю как её не поломать почти на уровне инстинктов.... Но было забавно видеть два разных указателя, один со структурой и один с данными. Суть происходящего в том, что когда вызывается метод все типы определены и соответственно математика каста работает.
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
UB потому что  придется делать внутри

list_member<X> end_
X* end_node() { return static_cast<X*>(end_); }
А почему end_ не указатель? В общем если там указатель - то все прекрасно, если там оно само - все резко усложняется.
источник

MK

Mikhail Kalugin in pro.cxx
Mikhail Kalugin
В общем, каст легальный и работает. Рекурсию того вида, что я предполагал получить очень сложно (компилятор умный - экземпляр не до конца определенного типа не даст создать, только указатели на него). Что из себя представляет list_member? P.S. А может, я просто слишком долго играл с CRTP (всякие ATL, WTL, самописные фреймворки) и знаю как её не поломать почти на уровне инстинктов.... Но было забавно видеть два разных указателя, один со структурой и один с данными. Суть происходящего в том, что когда вызывается метод все типы определены и соответственно математика каста работает.
Посмотрел реализацию списков GNU (из gcc 10) там все еще то же самое - на самом деле. node_base просто с указателями на соседей (node_base) если хочется, можно заменить на указатели на node template<class T> struct node_base {T *pPrev; T *pNext;}; template <typename T> struct node: node_base<node<T>> {T value;};
источник

DS

Dmitry Sokolov in pro.cxx
Mikhail Kalugin
А почему end_ не указатель? В общем если там указатель - то все прекрасно, если там оно само - все резко усложняется.
Неважно. Каст нелегальный.
> If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
Неважно. Каст нелегальный.
> If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.
В действующем стандарте этого нет. Это черновик на самом деле. Подозреваю, что gcc попытались это реализовать и все поломали.
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
Неважно. Каст нелегальный.
> If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.
Указатели в нашем случае не prvalue - они lvalue.
источник

DS

Dmitry Sokolov in pro.cxx
Mikhail Kalugin
Указатели в нашем случае не prvalue - они lvalue.
static_cast<T*>(&end_)
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
static_cast<T*>(&end_)
Ну, в принципе логика ясна - такое делать не стоит (теряются данные), скорее всего 11 пункт про это.
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
static_cast<T*>(&end_)
Точнее, в моей версии компиляторов это сработает, но будет мусор в полях T
источник

MK

Mikhail Kalugin in pro.cxx
Dmitry Sokolov
static_cast<T*>(&end_)
Думаю, по этому они ужесточили стандарт - тут просто двигать туда-сюда указатель не получится. CRTP безопасна потому, что мы приводим D*->B*->D* то есть где-то в base просто восстанавливаем исходный указатель.
источник

SI

Shack Ira in pro.cxx
Ребят, односвязный список реализуется самостоятельно, или есть готовый класс?
источник

VD

Vlad Doc in pro.cxx
Shack Ira
Ребят, односвязный список реализуется самостоятельно, или есть готовый класс?
std::list. И да @supapro
источник

DP

Denis Paukaev in pro.cxx
std::forward_list вроде же
источник

D

Danya in pro.cxx
Vlad Doc
std::list. И да @supapro
Это двусвязанный
источник

D

Danya in pro.cxx
Denis Paukaev
std::forward_list вроде же
+
источник

D

Danya in pro.cxx
Только нафиг он нужен был бы
источник