1-我遗漏了一些关于移动语义的东西,在这种情况下有理由不发出警告,或者 gcc 检查不够好?
代码是错误的,所以警告会很好。G++ 不够聪明,无法“看穿”对std::move
. 通过引用函数(该函数可能会初始化变量)传递未初始化的变量是有效的,因此调用std::move
自身不会触发警告。因为q
被分配了一个值,所以它似乎被初始化给编译器。
如果我打开优化以便 G++ 内联调用,std::move
那么我会收到来自 G++ 4.7 的错误:
f.cc: In function ‘int main()’:
f.cc:6:9: warning: ‘p’ is used uninitialized in this function [-Wuninitialized]
这是因为对编译器的调用std::move
不再是“不透明的”,当它分析内联代码时,它可以看到p
永远不会被赋值。编译器仍然不够聪明,看不到它q
永远不会得到一个好的值,里面的转换std::move
可能会让编译器感到困惑。
2-下一个代码应该发出警告吗?
不std::move
,不会改变指针等基本类型,因此不会改变 的值p
。标准库表示,对象在被移动后处于“有效但未指定”状态,因为标准通常不定义移动构造函数或移动赋值运算符的确切行为,但对于基本类型,例如int
和char*
没有移动构造函数。std::move(p)
只是将对象转换为右值,它不会改变它,并且q
用值初始化也不会改变它 - 它只是复制值。
3-其他工具/编译器可以检查这些错误吗?
即使启用了优化,Clang 和 ICC 也无法警告第一个示例。
请注意,尽管警告非常有用,但编译器并不完美,不可能警告所有不安全的代码。当不安全的代码没有收到警告时,你不应该感到完全惊讶(也许打开一个错误报告让编译器请求改进)——这并不意味着代码是好的。没有警告并不意味着没有错误。