0

I'm new to C++ and I noticed some inconsistency while working with the size() method. Why in the example code below I have 2 different results, one when the size is parsed and other when don't. I'm missing something?

#include <iostream>
#include <vector>

using namespace std;

int main()
{   
    vector<int> arr = { 2, 3, 1, -4, -4, 2 };
    cout<< arr.size() << endl; // 6
    cout<< (-1 % arr.size()) << endl; // 3, incorrect without parsing
    cout<< (-1 % 6) << endl; // -1
    cout<< (-1 % (int)arr.size()) << endl; // -1 UPDATE, correct answer onlye when parsed
}

Update:

Yes, I do have a typo in the comment the correct value for the last answer is -1 again, it's different than the second output 3.

I actually noticed the issue, while doing a code challenge. The solution in the code example was parsed, so I was curious "If I don't parse it will I have a different result" and In fact I did. So I open a online editor to test this beahivor. This is the online code

Juan P. Ortiz
  • 568
  • 1
  • 6
  • 21
  • Afaik the % (modulus) of a negative number is found by ignoring the sign, so -1 % 6 = 5. – Dorian Jun 18 '20 at 06:45
  • What [C++ programming book](https://stroustrup.com/programming.html) did you read? See also [this C++ reference](https://en.cppreference.com/w/cpp) – Basile Starynkevitch Jun 18 '20 at 06:46
  • 1
    `using namespace std;` is a bad habit to get into and if you can stop now you might avoid a whole lot of headaches in the future. The `std::` prefix is there for a reason: It avoids conflict with your own classes, structures and variables. – tadman Jun 18 '20 at 06:48
  • The last one must be -1, not 3. – Lukas-T Jun 18 '20 at 06:49
  • 1
    Note that `size()` returns `size_t` which is `unsigned` and that has a huge impact on the result. – tadman Jun 18 '20 at 06:50
  • @tadman It does, although I don't understand why `-1 % unsignedSix` == 3. That's not the result I'd expect if an implicit conversion took place... – Benj Jun 18 '20 at 06:54
  • @Benj It's because it doesn't. I tested the code and it gave me 6, 3, -1, -1 for each item there, as expected. The `3` is presumably a transcription error. – tadman Jun 18 '20 at 06:55
  • I can't reproduce it ¯\\_(ツ)_/¯ : https://ideone.com/9D2IoD – ΦXocę 웃 Пepeúpa ツ Jun 18 '20 at 06:56
  • @tadman My compiler gives 3 for `-1 % unsignedSix` – Benj Jun 18 '20 at 06:59
  • @Benj Which compiler? Which architecture? – tadman Jun 18 '20 at 07:01
  • @Bathsheba - Right, `4294967295 % 6` does indeed give 3. – Benj Jun 18 '20 at 07:03
  • `size_t` might be 64-bit (but 3 comes in both cases this time, unlike in the question I've linked – M.M Jun 18 '20 at 07:17

1 Answers1

4

There is a typo in your question: the last cout outputs -1 unless your compiler is defective (unlikely), or you have a pre C++11 compiler with a curiously documented behaviour of % for a negative first argument (extremely unlikely).

In the case of -1 % arr.size(), -1 is converted to an unsigned type since arr.size() is required by the C++ standard to return an unsigned type.

-1 % 6 is -1 from and including C++11. Prior to that, the value was implementation defined.

You'd find it instructive to inspect the output of

std::cout << (-1 % 6U) << std::endl;

which, in your case, will be 3.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483