c++g++compiler-optimization

Arithmetic error caused by -O3 option on g++


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


Solution

  • 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.