繁体   English   中英

MSVC将仅移动结构参数解释为指针

[英]MSVC interpreting move-only struct argument as a pointer

我有一个简单的单成员结构,删除了复制结构/赋值,以及默认的移动构造/赋值。 我试图通过值将这些结构中的一个传递给函数并返回该成员 - 非常简单。

struct NoCopy {
    explicit NoCopy(int x) : x{x} {}

    NoCopy(const NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;

    NoCopy(NoCopy&&) = default;
    NoCopy& operator=(NoCopy&&) = default;

    int x;
};

// noinline to ensure the crash is reproducible in release
// not required to reproduce the problem code
__declspec(noinline) int problem_function(NoCopy x) {
    return x.x;
}

int main() {
    return problem_function(NoCopy{ 1 });
}

问题是当使用MSVC编译时,此函数崩溃。

查看反汇编,似乎在删除复制构造函数时,MSVC会尝试将x解释为NoCopy* ,并且后续成员读取会导致分段错误。

这是一个godbolt的例子,用gcc和clang作为参考: https ://godbolt.org/z/jG7kIw

请注意,gcc和clang都按预期运行。 另请注意,这在优化和未优化的构建中都会发生,并且似乎会影响MSVC 2015和2017。

作为参考,我正在使用Visual Studio Professional 2015(14.0.25431.01 Update 3)在我的机器上进行编译 - 我主要测试x64版本。 我的崩溃复制平台工具集设置为v140。

所以我的问题是:对此有任何合理的解释,或者我正在查看编译器错误。

编辑:我在这里提交了一份错误报告

编辑#2:如果像我一样,你遇到了类似的问题并且无法轻易更新VS - 似乎手动定义移动构造函数/赋值操作符而不是使用= default会导致MSVC在调用站点吐出正确的代码并避免崩溃。 这是一个新的魔咒

因此,像std :: unique_ptr这样的东西似乎没有受到影响。 结构大小似乎也是一个因素。

除了一个令人震惊的编译器bug之外,我看不出这是怎么回事。 代码有效。

在两个MSVS版本中已经破坏了如此基本的东西似乎很奇怪,但如果我不得不猜测它是由于相对较新的C ++ 17拷贝省略支持。 (当然,在这种情况下,我在某种程度上使用了“支持”一词。)

(OP的错误VS在线筹集这里 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM