G ++ -Wreorderのポイントは何ですか?
-
11-09-2019 - |
質問
G ++ -Wallオプションは-Wreorderが含まれています。何このオプションが行うことは以下の通りです。誰かが(-Wallにデフォルトでこれをオンにすることは、特に十分な)を気にする理由それは私には明らかにされていません。
-Wreorder (C++ only) Warn when the order of member initializers given in the code does not match the order in which they must be executed. For instance: struct A { int i; int j; A(): j (0), i (1) { } }; The compiler will rearrange the member initializers for i and j to match the declaration order of the members, emit-ting a warning to that effect. This warning is enabled by -Wall.
解決
考えてみます:
struct A {
int i;
int j;
A() : j(0), i(j) { }
};
今i
はいくつかの未知の値ではなく、ゼロに初期化されます。
あるいは、i
の初期化は、順序が重要であるため、いくつかの副作用を有することができます。例えばます。
A(int n) : j(n++), i(n++) { }
他のヒント
問題は、誰かが(私、その後、最初のj)をコンストラクタでメンバ初期化子のリストを見て、彼らはその順序で実行していると思うかもしれないということです。彼らは、彼らはメンバーがクラスで定義された順序で実行されていません。
あなたはA(): j(0), i(j) {}
を書いたとします。誰かがそれを読んで、私はあなたはそれが初期化されていなかったため、自身のジャンクが含まれているJ、でそれを初期化するのでそれは、ない値0で終わると思うかもしれません。
警告がうまくいけば、より多くの魚に見えるA(): i(j), j(0) {}
を書くためにあなたを思い出させます。
他の回答には、警告のためのオプションを正当化するいくつかの良い例を提供しています。私はいくつかの歴史的背景を提供しようと思いました。 C ++の生みの親、ビャーネ・ストロヴストルップは、(C ++プログラミング言語のrel="noreferrer">彼の本の
メンバー含むクラスのボディの前にコンストラクタが呼び出されますは。コンストラクタは、彼らはむしろ彼らは初期化子リストに表示される順序よりも、クラスで宣言された順序で呼び出されます。混乱を避けるためには、宣言順に初期化子を指定するのがベストです。メンバーのデストラクタは、建設の逆の順序で呼び出されます。
自身のコンストラクタが実行される
このはあなたをかむことができます。考えてみます:
int foo() {
puts("foo");
return 1;
}
int bar() {
puts("bar");
return 2;
}
struct baz {
int x, y;
baz() : y(foo()), x(bar()) {}
};
上記直感的に1は、初期化子リストに書かれた順序があることを前提としていますにもかかわらず、その後、「foo」という「bar」を出力します。
x
とy
コンストラクタといくつかのユーザ定義型である場合にあるいは、そのコンストラクタは、同じ非自明な結果で、副作用を有することができる。
一方の部材の初期化子は、他の部材を参照するときにも現れることができます。
j
がi
前に初期化されたばかりのように見えるので、警告が存在します。一つのように、他の初期化に使用される場合、これは問題となる
struct A {
int i;
int j;
A(): j (0), i (this->j) { }
};
あなただけのコンストラクタを見てみると、、このがの安全に見えます。しかし、現実には、j
はまだi
を初期化するために使用される時点では初期化されていない、と予想されるようにコードが動作しません。したがって、警告ます。