c++ - 是 Visual C++ 优化器错误还是我的代码中有错误?

标签 c++ visual-c++ visual-studio-2017 compiler-bug

我们正在从 VS2013 迁移到 VS2017。

下面是一个可能不是最小的代码示例,但它是我能做的最好的。 它的要点是一个特定的浮点值被发送到一个函数,但是该函数接收到错误的值 - 这是因为调用函数中的寄存器不匹配。

此代码在 VC141(VS 2017)和 VC140(VS 2015)上不正确运行,但在 VC120(VS 2013)和随附的 clang 版本上正确运行内置 VS 2017(带有 Microsoft CodeGen (v141_clang_c2) 的 Clang - 无论它是什么 clang 兼容版本)。

在 Release 中针对 x64 平台进行编译时会出现此问题(经过优化)。删除优化时代码工作正常,所以我猜是优化器。 调用 test() 时,错误行为出现在 badFunc() 中。

代码:

#include <iostream>
#include <vector>

struct FloatWrapper
{
    FloatWrapper() : m_value(0) {}
    explicit FloatWrapper(float value) : m_value(value) {}
    float getValue() const { return m_value; }

private:
    float m_value;
};

class Tester
{
public:

    virtual bool test(FloatWrapper elevation) const
    {
        std::cout << "Expected=" << m_expected.getValue() << ", received=" << elevation.getValue() << '\n';
        return elevation.getValue() == m_expected.getValue();
    }

    Tester(FloatWrapper expected) : m_expected(expected)
    {
    }

    FloatWrapper m_expected;

};

struct DataBlock
{
    FloatWrapper a, b;
};

bool badFunc(const Tester& query, std::vector<DataBlock> blocks)
{
    auto block = blocks[0];

    if (!query.test(block.b))
    {
        std::cout << "Tried to send " << block.b.getValue() << '\n';
        return false;
    }

    return true;
}


int main(int argc, const char** argv)
{
    DataBlock block;
    block.b = FloatWrapper(0.2f);

    Tester tester(block.b);

    return badFunc(tester, { block }) ? 0 : 1;
}

编译命令行:

/GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Fd"x64\Release\vc141.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\compiler_bug_vc14.pch" /diagnostics:classic 

链接器命令行:

/OUT:"x64\Release\compiler_bug_vc14.exe" /MANIFEST /LTCG:incremental /NXCOMPAT /PDB:"x64\Release\compiler_bug_vc14.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FULL /MACHINE:X64 /OPT:REF /INCREMENTAL:NO /PGD:"x64\Release\compiler_bug_vc14.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Release\compiler_bug_vc14.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 

最佳答案

答案是肯定的——这是一个优化器错误。 微软表示他们修复了它,目前(2017 年 9 月 24 日)正在等待发布。

参见 https://developercommunity.visualstudio.com/content/problem/84976/optimizer-bug-in-vc140141-passing-the-wrong-float.html

关于c++ - 是 Visual C++ 优化器错误还是我的代码中有错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45296810/

相关文章:

c++ - ffmpeg/Libavcodec 找不到编解码器

c++ - 在现有的visual studio 2017中下载c++

git - 在Visual Studio 2017中,通过SSH进行Git Push提交失败

asp.net-core - ASP.NET Core 2.x OnConfiguring 从 appsettings.json 获取连接字符串

c++ - 当我们尝试使用 istream::getline() 和 std::getline() 提取文件中出现 `eof` 字符的行时,实际会发生什么

c++ - 处理嵌套 std::any_of 的模板函数

c++ - 为什么 decltype(a, b) 被评估为引用?

c++ - 字符串、CString、QString 有什么区别?

c++ - 模板函数特化默认参数

c# - 从 asp.net core 连接到 Oracle 数据库