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- 次のコードは警告をスローする必要がありますか?
No.std::move
はポインタなどの基本的な型を変更しないため、 の値はp
変更されません。標準ライブラリは、オブジェクトが移動された後、「有効だが未指定」の状態のままであると述べています。これは、標準では一般に移動コンストラクターまたは移動代入演算子の正確な動作が定義されていないためint
ですchar*
。移動コンストラクターはありません。std::move(p)
オブジェクトを右辺値にキャストするだけで、オブジェクトは変更されq
ず、値で初期化しても変更されません-値をコピーするだけです。
3- 他のツール/コンパイラでこれらのエラーをチェックできますか?
最適化をオンにしても、Clang と ICC は最初の例について警告しません。
警告は非常に便利ですが、コンパイラは完全ではなく、すべての安全でないコードについて警告することは不可能であることに注意してください。安全でないコードに対して警告が表示されなくても (コンパイラにバグ レポートを開いて改善を要求するなど)、まったく驚かないでください。それは、コードに問題がないことを意味するものではありません。警告がないからといって、バグがないわけではありません。