次のコードを検討してください。
class Foo {
public:
explicit Foo(double) {}
};
Foo * test();
Foo * test() {
return new Foo(Foo(1.0)); // (1)
}
私の質問は行 (1) に関するものです。これは、追跡に時間がかかったバグと非常によく似ています。コピー/貼り付けエラーにより、型が 2 回指定されていることに気付きませんでした。正しい行は明らかに次のとおりです。
return new Foo(1.0);
興味深いことに、この変更も警告なしでコンパイルされるようです。
return new Foo(Foo(Foo(Foo(1.0))));
-Wall -Weverything
これらの例は、フラグを使用しても、clang で警告なしにコンパイルされるのはなぜですか? Foo のインスタンスを有効な引数Foo::Foo(double)
として受け入れるのはなぜですか? double
これは、新しい演算子の特異な動作ですか?
私の元のコードはより大きなコンテキストにあり、2 つの LLVM-3 ベースのコンパイラでテストされました。どちらも警告やエラーなしでコンパイルされました。1 つでは、コードは実際に期待どおりに機能し、実際、バグがあることにしばらく気づきませんでした。もう 1 つの例では、Foo のインスタンスが非常に奇妙に動作しました。正確に説明することはできませんが、返されたポインターの後のコピーが「魔法のように」元の値とは異なる値になり、2 つの協調動作の間で不一致の状態が発生したかのようでした。共有 Foo への同等のポインターを保持するはずだったオブジェクトが、何らかの理由で割り当て後に異なる値を保持していました。ここで何が起こっているのかを理解するまでは、本当に奇妙に思えます!
興味深いことに、以下は両方のコンパイラでコンパイルされます。
class Foo { public: explicit Foo(double) {} };
class Bar { public: explicit Bar(double) {} };
Foo * testFoo() { return new Foo(Foo(1.0)); }
Bar * testBar() { return new Bar(Bar(1.0)); }
しかし、次のバージョンはそうではありません:
Foo * testFooBar() { return new Foo(Bar(1.0)); }