6

Given this Example:

std::vector<int> numbers = {5,6,7}; //size is 3
int i = -1; 
std::cout << i % 3 <<"\n";                  // output: -1
std::cout << i % numbers.size() << "\n";    // output: 0

basically in both statements im processing -1 % 3 but the compiler outputs different numbers. I don't understand this outcome, maybe someone can explain it to me.

edit: as @Chris,@Keith Thompson @AnT suggested the snippet

std::cout << std::numeric_limits<std::size_t>::max() % 3 <<"\n";     //output: 0
std::cout << i % numbers.size() << "\n";                            // output: 0

prints the expected output. Thanks for the helpful advice to everyone!

Grundkurs
  • 199
  • 1
  • 8

2 Answers2

8

i % 3 is what you expect and, since C++11, has defined semantics rather than having an implementation-defined (if I recall correctly) result.

numbers.size() has an unsigned type (std::size_t). Assuming size_t is as big as int or bigger, i is converted to the same unsigned type before the operation is performed. The value i gets will be the maximum value for that type, which looks to be divisible by 3 for you.

chris
  • 60,560
  • 13
  • 143
  • 205
  • 3
    As a side-note, cranking up the warning-level on the compiler should have caught the sign-mismatch. – Deduplicator Mar 26 '15 at 01:42
  • @Deduplicator, Interesting, I didn't know that. Apparently [Clang doesn't](http://coliru.stacked-crooked.com/a/e425e23f148a1f03), [nor GCC](http://coliru.stacked-crooked.com/a/7353cc43b82d22c3), or at least these versions. – chris Mar 26 '15 at 01:44
  • Try `-Weverything`, and see which warning they threw out of `-Wextra`. – Deduplicator Mar 26 '15 at 01:48
  • @Deduplicator, Ah, I see. Now I'm thinking of whether it's worth adding that specific warning (`‑Wsign‑conversion`) to my options. Thanks! – chris Mar 26 '15 at 01:49
0

The problem is % of negative numbers is not well-defined in C++.

Joshua
  • 40,822
  • 8
  • 72
  • 132