2017-07-25 33 views
10

Jesteśmy w trakcie migracji z VS2013 do VS2017.Czy jest to błąd optymalizatora Visual C++, czy mam błąd w moim kodzie?

Poniżej znajduje się prawdopodobnie nie tak minimalna próbka kodu, ale jest to najlepsze, co mogę zrobić. Istotą jest to, że określona wartość zmiennoprzecinkowa jest wysyłana do funkcji, ale funkcja otrzymuje błędną wartość - dzieje się tak z powodu niedopasowania rejestrów w funkcji wywołującej.

Ten kod działa nieprawidłowo na VC141 (VS 2017) i VC140 (VS 2015), ale działa poprawnie na VC120 (VS 2013) oraz w wersji dzyń który przychodzi zbudowany z VS 2017 (Clang z Microsoftem CodeGen (v141_clang_c2) - niezależnie od wersji kompatybilnej z klangiem).

Problem pojawia się podczas kompilacji na platformę x64 w wersji (przy optymalizacji). Podczas usuwania optymalizacji kod działa dobrze, więc zgaduję, że jest to optymalizator. Niewłaściwe zachowanie jest w badFunc() podczas wywoływania test().

Kod:

#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; 
} 

kompilatora wiersza polecenia:

/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 

Linker linii komend:

/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 
+1

Wygląda to na błąd kompilatora. Mogę to odtworzyć na moim komputerze. Powinieneś zgłosić to firmie Microsoft. –

+0

Wygląda jak błąd dla mnie, zgłoś błąd na [connect.microsoft.com] (https://connect.microsoft.com/VisualStudio). –

+4

Otwarty problem z połączeniem MS: https://connect.microsoft.com/VisualStudio/feedback/details/3138251/optimizer-bug-in-vc140-141-passing-trong-float-value-to-afunction – Asaf

Odpowiedz