Asa*_*saf 10 c++ visual-c++ compiler-bug visual-studio-2017
我们正在从VS2013迁移到VS2017.
下面是一个可能不是那么简单的代码示例,但它是我能做的最好的.它的要点是一个特定的浮点值被发送到一个函数,但该函数接收到错误的值 - 这是因为调用函数中的寄存器不匹配.
此代码运行错误的VC141(VS 2017)和VC140(VS 2015年),但运行正常的VC120(VS 2013),并在其上已内置在VS 2017年(铛与微软的CodeGen(v141_clang_c2)铛版本-无论铛兼容它的版本).
在Release中编译x64平台时(使用优化)会出现问题.删除优化时,代码工作正常,所以我的猜测是优化器.badFunc()
调用时出现了错误的行为test()
.
代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
编译器命令行:
/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
Run Code Online (Sandbox Code Playgroud)
链接器命令行:
/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
Run Code Online (Sandbox Code Playgroud)
答案是肯定的——这是一个优化器错误。微软表示他们已修复该问题,目前(2017 年 9 月 24 日)待发布。