Search code examples
c++intinteger-overflowfixed-width

Understanding numerical overflow in C++


I am trying to understand better how overflows behaves in C++. Consider the following MWE (must check for integer literals):

#include <cstdint>
#include <iostream>
#include <iomanip>

int main() {
    uint64_t known    = 6049417284;  // Known solution to operation.
    uint32_t option_1 = 77778u;      // Using 32 bits for operands.
    uint64_t option_2 = 77778ull;    // using 64 bits for operands.

    uint64_t sol_option_1 = option_1*option_1;
    uint64_t sol_option_2 = option_2*option_2;

    std::cout << std::boolalpha << (sol_option_1 == known) << std::endl;
    std::cout                   << (sol_option_2 == known) << std::endl;
}

Execution:

false
true

Why does it overflow with operands using 32 bits, even tough I explicitly request 64 bits to receive the solution?

My impression is that during run-time, C++ creates a temporary rvalue, whose precision is that from the operands, i.e. 32 bits. This overflows, and this result from an overflow is copied to the sol_option_1 variable, which receives the result from an overflow.


Solution

  • The answer is very simple: C++ doesn't care about what the result is being assigned to, it just takes the expression option_1 * option_1 and evaluates that. Then, it performs the assignment with the result. Note that you can also choose not to assign the result of an expression anywhere but that shouldn't affect the expression's evaluation.