Начиная с C ++ 11 я использую троичный оператор для перемещения или броска в зависимости от некоторых условий, но с последним GCC (9.1 и trunk) больше не работает.
Я уменьшил проблему доэтот пример ( Постоянная ссылка Wandbox ):
#include <iostream>
#include <memory>
int main()
{
auto p = std::make_unique<int>();
std::cout << "p.get(): " << p.get() << std::endl;
{
std::cout << "Move p into q" << std::endl;
auto q = p ? std::move(p) : throw std::invalid_argument{"null ptr"};
std::cout << "q.get(): " << q.get() << std::endl;
}
std::cout << "p.get(): " << p.get() << std::endl;
return 0;
}
Он работает с GCC 8.3 и старше, а также с каждой версией Clang;и p
перемещается:
p.get(): 0xde5c20
Move p into q
q.get(): 0xde5c20
p.get(): 0
Но теперь с GCC 9.1 и более поздними версиями он не работает:
p.get(): 0x1d89150
Move p into q
q.get(): 0x1d89150
p.get(): 0x1d89150
А затем программа падает из-за двойного освобождения.
Это ошибка в GCC 9.1 / trunk?Или последний GCC - единственный, кто делает правильные вещи, и это не является допустимым C ++?