2
votes

I returned to an old project to find that it no longer compiles with the latest g++ version (5.2.0).
I get the cryptic error:

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]

By commenting out blocks of code in that function until it compiled again, I traced the error to this line:

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

where tmpCont is of type std::set<actionPair, execOrder> , whereexecOrder is:

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

and Keys are std::vector<uint64_t>. If I replace the std::find(...) statement in the second if block, g++ successfully compiles this code. However, I am still confused, and don't know how to fix this issue.

My compiler flags are

-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

(essentially clang's -Weverything at the time)

1
This is a warning, not normally an error, but you specifically requested to turn all warnings into errors by passing the -Werror option. Why do you have it there? Hell, I think it wouldn't normally even be a warning by default, except you also turned -Wstrict-overflow to the highest level of 5. - user743382
@hvd You're right, it compiles with -Wstrict-overflow=2 or 1. Is it really a false positive though, or is there something I can do here to remove the warning altogether? I have -Werror and all those warnings on because I'm still new and trying to learn to write proper code. - andrei
I believe this warning usually applies to lines of code that are optimized out based on assumptions about overflows never occurring. A very insightful example is found in stackoverflow.com/questions/22798709/… Perhaps you should look for a situation similar to that example to understand why you get this warning. I can't see it from the code you have supplied, but perhaps it's a matter of looking more carefully and with more context. - jogojapan
Compiler warns that it transforms code (similar to) from a + b < c to a < c - b (assuming no overflow), so if you can change yourself, you may get rid of the warning. - Jarod42
@jogojapan Thanks. I've also read link before posting, but wasn't able to solve my case because the issue seems to be in the stdlib function std::find. - andrei

1 Answers

1
votes

One way or another, this is a GCC bug. Either the std::find code is correct and the warning is wrong, or the warning is right and the std::find implementation fails to properly handle all edge cases. That is up to the GCC maintainers to sort out.

As a workaround, turn off the warning for those few lines only.