Search code examples
c++vectorvscode-debugger

What is wrong with assigning a long value to an index of a ll vector? INT Overflow in vector<long long>


Why do I get an INT overflow error when assigning a long value to 'out[0]' in the following code? I have declared out as a vector already.

vector<long long> foo(int m, int n) {
        vector<long long> out(5);
        // why is there an overflow of int ?? 
        out[0] = (m-1)*(n-1);
        cout << out[0] << endl;

        out[0] = (long long) (m-1)*(n-1);
        cout << out[0] << endl;
        ..
        ..
        return out;
}

I also found that typecasting the RHS works. But I'm not sure that is the intended way to assign 'long long' values.

COUT: 
-615099295
3679868001
For values: m=40000 and n=92000

Please help me understand why I can't assign a value to the index normally, and what is the proper way of doing so. (I know this might be a newbie question, but I couldn't find much about this.)

I needed to assign values to this output vector using a map in my code, which I found out was returning garbage, and only after a good time spent debugging, I found a problem with the initial assignment itself.

Upon reviewing the SO related questions I found that LL needs to be mentioned after the number, but how do I do that with an expression of int variables?


Solution

  • In ...

    out[0] = (m-1)*(n-1);
    

    ... you perform the multiplication using int. It doesn't matter that out[0] is a long long&. The conversion to long long happens after the multiplication has been performed.

    When you cast m - 1 to long long then n - 1 will also be implicitly converted to long long and the multiplication is then done using long long.

    In modern (C++11 or later) C++, it's preferable to use static_cast<long long> instead of the old style (long long) though:

    out[0] = static_cast<long long>(m-1) * (n-1);
    

    I also found that typecasting the RHS works. But I'm not sure that is the intended way to assign 'long long' values.

    You cast the LHS operand in the multiplication and it doesn't matter if you cast LHS, RHS or both to long long. As long as you cast at least one of them, the other operand will follow.

    Yes, in situations like this, it's the correct way. Another way would be to change the type of m and n to long long.