I have the following (very simple) code:
#include <cstdint>
#include <iostream>
#include <vector>
int main(void)
{
std::vector<int64_t> result;
int64_t seed = 9564738543572813LL;
int64_t fact = 18465439963655325LL;
for (int i = 0; i < 100 ; i++)
{
seed = seed * fact ;
result.push_back(seed);
}
std::cout << result[0] << ", " << result[1] << std::endl ;
}
If I compile it and run like this is all OK
g++ a.cpp -o a
./a
3551237700689479225, 6924873214268169461
But if I ask for -O3 optimization the results are weird!
g++ -O3 a.cpp -o a
./a
9223372036854775807, 9223372036854775807
What am I doing wrong? I am using g++ 11.4.0 on Ubuntu 22.04
What am I doing wrong?
Signed multiplication overflow is undefined in C programming langauge. GCC has also documentation about it https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Signed-Overflow.html . It is not know what should be the result of your code - it can be anything. See also Undefined, unspecified and implementation-defined behavior
If think you meant to do this:
seed = (int64_t)((uint64_t)seed * (uint64_t)fact);
or shorter, deas the same:
seed = (uint64_t)seed * fact;
Consider using sanitizers, analyzers and linters for your code. Using gcc -fsanitize=undefined
will detect errors like in your code.