Код выводит мусор. Address sanitizer сообщает "stack-use-after-scope". Проблема воспроизводится только на GCC (проверял на 8.2.0 и 5.4) и только с оптимизацией -O0 или -O1,
точнее на высоких уровнях оптимизации печаетается правильный результат, но AddressSanitizer все равно ругается.
Здравствуйте, Vinick, Вы писали:
V>Помогите разобраться, что происходит и что я сделал неправильно.
Берёшь указатель на временный объект и используешь его после смерти объекта.
С movе-семантикой проблема непосредственно не связана.
V>// <---------если здесь передавать аргумент по значению, то проблема исчезает.
Здравствуйте, watchmaker, Вы писали:
W>Здравствуйте, Vinick, Вы писали:
V>>Помогите разобраться, что происходит и что я сделал неправильно. W>Берёшь указатель на временный объект и используешь его после смерти объекта.
А можно пальцем ткнуть? Я хоть убей не вижу. Вроде все объекты на которые хранятся указатели, лежат на стеке в main.
Здравствуйте, Vinick, Вы писали:
V>Помогите разобраться, что происходит и что я сделал неправильно.
Добавляй Move assignment operator да и конструкторы копирования я бы тоже добавил, раз уж начал руками перемещение писать, то описывай все операторы.
Здравствуйте, Vinick, Вы писали:
V> auto op = Op<decltype(d)>(std::move(d)); V>.... V>.... V>.... V> auto gop = Op<decltype(g)>(std::move(g)); V>....
Здесь в шаблон уходит ссылка. Т.е. эти gop и op хранят ссылки, а не объекты. Естественно привязанные к ним объекты дохнут и ты получаешь проблему.
ИМХО, перестарался с автовыводом типов.
Добавление в Op и Cons std::remove_reference_t<D> решает проблему.
Здравствуйте, Vinick, Вы писали:
V>А можно пальцем ткнуть? Я хоть убей не вижу. Вроде все объекты на которые хранятся указатели, лежат на стеке в main.
Здравствуйте, Vinick, Вы писали:
V>Код выводит мусор. Address sanitizer сообщает "stack-use-after-scope". Проблема воспроизводится только на GCC (проверял на 8.2.0 и 5.4) и только с оптимизацией -O0 или -O1, V>точнее на высоких уровнях оптимизации печаетается правильный результат, но AddressSanitizer все равно ругается.
Здравствуйте, wander, Вы писали:
W>Здесь в шаблон уходит ссылка. Т.е. эти gop и op хранят ссылки, а не объекты. Естественно привязанные к ним объекты дохнут и ты получаешь проблему. W>ИМХО, перестарался с автовыводом типов.
W>Добавление в Op и Cons std::remove_reference_t<D> решает проблему.
вот так подфиксил: https://ideone.com/KIioaB
кое-где добавил std::decay_t, кое-где при move сырого указателя сделал зануление в источнике (для исходной проблемы неактуально, однако так желательно делать)
Я бы немного подругому сделал (как по мне, корректность состояния Op и Cons не должны зависеть от внешних действий; то, что там внутри нужны именно объекты, мне кажется очевидным), ну да ладно
Здравствуйте, wander, Вы писали:
W>Здесь в шаблон уходит ссылка. Т.е. эти gop и op хранят ссылки, а не объекты. Естественно привязанные к ним объекты дохнут и ты получаешь проблему. W>ИМХО, перестарался с автовыводом типов.
Имхо, наступил на грабельку синтаксиса плюсов. Где T&& в объявлении функции по-разному трактуется для нешаблонных и шаблонных аргументов.
some foo(ValueType&& xvalue);
template<class GeneralizedReferenceType>
some bar(GeneralizedReferenceType&& glvalue);
Из-за чего и приходится явно расставлять remove_reference_t (или decay_t) и forward.