Подтвердить что ты не робот

Является ли это ошибкой оптимизатора Visual С++ или у меня есть ошибка в моем коде?

Мы переходим от VS2013 к VS2017.

Ниже, вероятно, не так минимальный образец кода, но это лучшее, что я мог сделать. Суть его в том, что определенное значение float отправляется функции, но функция получает неправильное значение - это из-за несоответствия регистров в вызывающей функции.

Этот код работает неправильно на VC141 (VS 2017) и VC140 (VS 2015), но работает правильно на VC120 (VS 2013) и на версии clang, которая приходит встроенный в VS 2017 (Clang с Microsoft CodeGen (v141_clang_c2) - любая версия, совместимая с Clang).

Проблема проявляется при компиляции для платформы x64 в Release (с оптимизацией). При удалении оптимизаций код работает нормально, поэтому я думаю, что это оптимизатор. Неправильное поведение находится в 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;
}

Командная строка компилятора:

/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 
4b9b3361