请考虑以下代码:
class Foo {
public:
explicit Foo(double) {}
};
Foo * test();
Foo * test() {
return new Foo(Foo(1.0)); // (1)
}
我的问题涉及第 (1) 行。这与我花了一些时间才找到的错误非常相似。由于复制/粘贴错误,我没有注意到该类型被指定了两次。正确的行显然是:
return new Foo(1.0);
有趣的是,此更改似乎也可以无警告地编译:
return new Foo(Foo(Foo(Foo(1.0))));
为什么这些示例编译时没有使用 clang 的警告,即使使用了-Wall -Weverything
标志?为什么Foo::Foo(double)
接受 Foo 的实例作为有效double
参数?这是 operator new 的一些特殊行为吗?
我的原始代码位于更大的上下文中,并使用两个基于 LLVM-3 的编译器进行了测试。两者都在没有警告或错误的情况下编译。有了一个,代码实际上按我的预期运行,事实上我有一段时间没有意识到有一个错误。另一方面, Foo 的实例表现得非常奇怪 - 我无法正确描述它 - 就好像返回指针的后续副本“神奇地”变成了与原始值不同的值,导致两个合作之间的状态不匹配应该持有指向共享 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)); }