6

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

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为好像它是 aNoCopy*并且随后的成员读取导致分段错误。

这是一个godbolt示例,gcc和clang供参考:https ://godbolt.org/z/jG7kIw

请注意,gcc 和 clang 的行为都符合预期。另请注意,这在优化和未优化的版本中都会发生,并且似乎会影响 MSVC 2015 和 2017。

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

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

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

编辑#2:如果像我一样,您遇到了类似的问题并且无法轻松更新 VS -手动定义移动构造函数/赋值运算符而不是使用似乎= default会导致 MSVC 在调用站点吐出正确的代码并避免迷恋;撞车;崩溃。这是一个新的神螺栓

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

4

1 回答 1

1

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

在两个 MSVS 版本中已经破坏了一些如此基本的东西似乎确实很奇怪,但如果我不得不猜测这可能是由于相对较新的 C++17 复制省略支持。(当然,在这种情况下,我使用的术语“支持”有点松散。)

(OP 的 VS 错误在这里在线提出。

于 2018-11-01T15:50:04.593 回答