C 风格的转换能否调用显式转换构造函数?
考虑以下代码:
class Vec3
{
public:
explicit Vec3(float All)
: X(All), Y(All), Z(All)
{
}
Vec3(float InX, float InY, float InZ)
: X(InX), Y(InY), Z(InZ)
{
}
Vec3()
: X(0), Y(0), Z(0)
{
}
float X, Y, Z;
};
void Morph(const Vec3& In, Vec3& Out)
{
Out = In;
}
int main(void)
{
float Array[3] = {1.0f, 2.0f, 3.0f};
Vec3 Morphed;
Morph((const Vec3&)Array[0], Morphed);
}
在 Microsoft VS2010 的编译器上,它将 (const Vec3&)Array[0]
行转换为 reinterpret_cast 和复制构造函数,以将参数传递给函数。 Morphed 的值为 [1.0f, 2.0f, 3.0f]。
在第三方的另一个编译器上,它将 (const Vec3&)Array[0]
转换为对 explicit Vec3(float)
的调用,然后将复制构造函数转换为将参数传递给函数。 Morphed 的值为 [1.0f, 1.0f, 1.0f]。
我通过查看两个编译器的反汇编验证了这一点:
VS2010:
483: float Array[3] = {1.0f, 2.0f, 3.0f};
0000000143E68049 movss xmm0,dword ptr [__real@3f800000 (145DA1F18h)]
0000000143E68051 movss dword ptr [rsp+28h],xmm0
0000000143E68057 movss xmm0,dword ptr [__real@40000000 (145DC9704h)]
0000000143E6805F movss dword ptr [rsp+2Ch],xmm0
0000000143E68065 movss xmm0,dword ptr [__real@40400000 (145DC9708h)]
0000000143E6806D movss dword ptr [rsp+30h],xmm0
484: Vec3 Morphed;
0000000143E68073 xorps xmm0,xmm0
0000000143E68076 movss dword ptr [rsp+58h],xmm0
0000000143E6807C xorps xmm0,xmm0
0000000143E6807F movss dword ptr [rsp+5Ch],xmm0
0000000143E68085 xorps xmm0,xmm0
0000000143E68088 movss dword ptr [rsp+60h],xmm0
485: Morph((const Vec3&)Array[0], Morphed);
0000000143E6808E lea rdx,[rsp+58h]
0000000143E68093 lea rcx,[rsp+28h]
0000000143E68098 call Morph (143E67FB0h)
其他编译器:
184: float Array[3] {1.0f, 2.0f, 3.0f};
0000000001E1F3B0 mov rax,qword ptr [000000000432D1B0h]
0000000001E1F3B7 mov qword ptr [rbp-14h],rax
0000000001E1F3BB mov edi,dword ptr [000000000432D1B8h]
0000000001E1F3C1 mov dword ptr [rbp-0Ch],edi
185: Vec3 Morphed;
0000000001E1F3C4 lea rdi,[rbp-130h]
0000000001E1F3CB call Vec3::Vec3() (0000000003C119C0h)
186: Morph((const Vec3&)Array[0], Morphed);
0000000001E1F3D0 lea rdi,[rbp-140h]
0000000001E1F3D7 vmovss xmm0,dword ptr [rbp-14h]
0000000001E1F3DC call Vec3::Vec3(float) (0000000003C119E0h)
0000000001E1F3E1 lea rdi,[rbp-140h]
0000000001E1F3E8 lea rsi,[rbp-130h]
0000000001E1F3EF call Morph(Vec3 const&,Vec3&) (0000000001E1F350h)
不用说,这会导致很多问题。哪个编译器是正确的?第三方代码依赖于微软的实现,但我们正在使用不同平台的不同编译器进行编译。
最佳答案
就 C++ 标准而言,将 float &
转换为 const Vec3 &
是未定义的行为。两种编译器都是正确的,因为代码不受 C++ 的保护。
如果您希望这是一个 protected 转换,您必须停止类型双关并将 float
数组真正复制到 Vec3
.
关于c++ - 调用显式转换构造函数的 C 风格转换是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18543090/