Although you believe your code is similar to this:
#include <iostream>
double f()
{
double x = 3;
return x * -1;
}
int main()
{
std::cout << f() << std::endl;
}
The code you have actually takes the type of x
from the result of a vector’s size()
– this returns a std::size_t
:
#include <cstdint>
#include <iostream>
double f()
{
std::size_t x = 3;
return x * -1;
}
int main()
{
std::cout << f() << std::endl;
}
What happens here is that a std::size_t
is multiplied by int
. The rules of promotion when one argument is signed and one unsigned say that (source: CppReference)
if the unsigned operand’s conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand’s type.
std::size_t
is usually higher rank than int
, so we are now multiplying 3 by (std::size_t)-1
– a large number. Then when we return
, this large number is converted to double
to match the signature of f()
.
The issue can be avoided a few ways:
- Store the result of
size()
into a variable of signed or floating-point type, and use that to multiply. - Convert the result of
size()
usingstatic_cast<>
to a signed or floating-point type when multiplying. - Multiply by a floating-point constant (e.g.
-1.0
) – this will cause the other argument to be promoted to floating-point.
solved Bad Math with value multiplied by -1?