2

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)

andrei
  • 33
  • 3
  • 2
    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. –  Sep 09 '15 at 12:12
  • @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 Sep 09 '15 at 12:23
  • 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 http://stackoverflow.com/questions/22798709/g-strict-overflow-optimization-and-warnings 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 Sep 09 '15 at 12:30
  • 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 Sep 09 '15 at 12:33
  • @jogojapan Thanks. I've also read [link](https://stackoverflow.com/questions/23906389/c-while-loop-optimization-not-working-properly) before posting, but wasn't able to solve my case because the issue **seems** to be in the stdlib function std::find. – andrei Sep 09 '15 at 12:34
  • Andrei, note that you do not use `-Werror` because you are a beginner. You use it because you are smart. People who do not use it have bugs in their software. I know. I worked in C/C++ for 20 years, and I have fixed many bugs just by using that one option on the command line. It is sad, really, that the language does not enforce all of those things. We'd end up with much better code. – Alexis Wilke Apr 20 '16 at 21:34

1 Answers1

1

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.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350