自C ++ 11起,我一直在根据某些条件使用三元运算符进行移动或抛出,但是使用最新的GCC(9.1和主干)后,它不再起作用。
我已将问题简化为此示例(Wandbox permalink):
JP
它适用于GCC 8.3及更早版本以及每个Clang版本;并且[{
'code': 'INVALID_PARAMETER',
'message': 'Expected GeoId, got "JP" for country',
'parameter': 'country'
}]>
被移动了:
#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 9.1和更高版本中它不起作用:
p
然后该程序由于两次释放而崩溃。
这是GCC 9.1 / trunk中的错误吗?还是最新的GCC是唯一做正确的事,这不是有效的C ++吗?
答案 0 :(得分:3)
此已经是一个错误。
由于尝试复制unique_ptr
(或者发生throw
都没有关系),要么是移动就是移动,否则编译将失败。
q.get() == p.get()
实际上表明内部结构已损坏,因为这不可能。
我同意cpplearner的说法,这是bug 90393(及其所有重复),据报道是在GCC 9.1中引入的。
要么降级,要么等待升级,要么将代码重构为漂亮的if
/ else
。 ?