2015-09-09 94 views
2

我返回到一箇舊項目,發現它不再編譯最新的g ++版本(5.2.0)。
我得到神祕的錯誤:g ++和嚴格溢出的問題

src/combos.cpp: In member function ‘void ComboHandler::execute(uint64_t) const’ 
src/combos.cpp:123:6: error: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Werror=strict-overflow] 
void ComboHandler::execute(const uint64_t Mods) const { 
    ^
src/combos.cpp:123:6: error: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Werror=strict-overflow] 
src/combos.cpp:123:6: error: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Werror=strict-overflow] 

註釋掉在該函數的代碼塊,直到它再次編譯,我跟蹤誤差這一行:

  tmpCont.insert(actionPair(el,tmpParams)); 

其中tmpContstd::set<actionPair, execOrder>型 ,其中execOrder是:

struct execOrder { 
    bool operator() (const actionPair& i, const actionPair& j) const { 
    /* keep comboObjects with identical combos */ 
    if((i.first->Keys==j.first->Keys) && (i.first->Mods==j.first->Mods)) return true; 

    /* comboObjects match if at least one key matches */ 
    for(const Combo::key_type::value_type &elval: i.first->Keys) 
    if(std::find(j.first->Keys.begin(),j.first->Keys.end(),elval)!=j.first->Keys.end()) { 
     /* don't keep matching combos */ 
     return false; 
    } 

    return true; 
} 

Keysstd::vector<uint64_t>。如果我替換第二個if塊中的std::find(...)語句,g ++會成功編譯此代碼。但是,我仍然感到困惑,不知道如何解決這個問題。

我的編譯器標誌是

-O2 -Wall -Wextra -std=c++11 -pedantic `sdl2-config --cflags` -Wabi -fabi-version=0 -ffor-scope -fstrict-enums -fuse-cxa-atexit -Wctor-dtor-privacy -Wnoexcept -Wstrict-null-sentinel -Wold-style-cast -Woverloaded-virtual -Wsign-promo -Wdouble-promotion -Wformat=2 -Winit-self -Wmissing-include-dirs -Wswitch-default -Wswitch-enum -Wunused-local-typedefs -Wuninitialized -fstrict-overflow -Wstrict-overflow=5 -Wtrampolines -Wfloat-equal -Wundef -Wshadow -Wcast-qual -Wcast-align -Wconversion -Wsign-conversion -Wlogical-op -Wmissing-declarations -Wpacked -Wredundant-decls -Winline -Wvector-operation-performance -Wno-unknown-pragmas -Wdeprecated -Wno-inline -Wno-switch-default -DDEBUG -g -Werror -pedantic-errors

(主要是鏗鏘的-Weverything當時)

+2

這是一個警告,通常不是錯誤,但是您特別要求通過傳遞'-Werror'選項將* all *警告轉換爲錯誤。你爲什麼在那裏?地獄,我認爲它通常甚至不會是默認的警告,除非你*也將* -Wstrict-overflow轉化爲最高級別5. – hvd

+0

@ hvd你說得對,它用-Wstrict-overflow編譯= 2或1.這是否真的是假陽性,還是我可以在這裏完成刪除警告?我有 - 錯誤和所有這些警告,因爲我還是新手,並試圖學會編寫正確的代碼。 – andrei

+0

我相信這種警告通常適用於根據關於永遠不會發生溢出的假設進行優化的代碼行。在http://stackoverflow.com/questions/22798709/g-strict-overflow-optimization-and-warnings中可以找到一個非常有見識的例子。也許你應該尋找類似於這個例子的情況來理解你爲什麼會得到這個警告。我無法從你提供的代碼中看到它,但也許這是一個更仔細和更多的上下文的問題。 – jogojapan

回答

1

這種或那種方式,這是一個GCC的bug。 std::find代碼是正確的並且警告是錯誤的,或者警告是正確的並且std::find實施無法正確處理所有邊緣情況。這取決於GCC維護人員的理解。

作爲解決方法,turn off the warning僅適用於那幾行。