1

Trying to compile the following line in my code breaks:

printf("%llu\n", 0x12345678 * 0x12345678);

I get this:

program.c:45:34: warning: integer overflow in expression [-Woverflow]
     printf("%llu\n", (0x12345678 * 0x12345678));

How do I fix this?

bjd2385
  • 2,013
  • 4
  • 26
  • 47
  • 6
    `0x12345678 * 0x12345678` --> `0x12345678ULL * 0x12345678` – BLUEPIXY Dec 21 '16 at 01:29
  • @BLUEPIXY I've never seen that before, but it fixes the warning. Thank you. – bjd2385 Dec 21 '16 at 01:31
  • @bjd2385 The key here is to understand what type that C uses for the _calculation_, which is determined based on the types of the operands. What type you store the end result in doesn't affect the type used for the calculation. – Lundin Dec 21 '16 at 09:50
  • @Lundin That makes a lot of sense. Even though my answer has been down voted (unsurprisingly), I've still learned an important concept here. – bjd2385 Dec 21 '16 at 13:34

1 Answers1

1

[After accept correction per @Lundin] comment

On your machine, 0x12345678 is narrower than unsigned long long - certainly a signed long or maybe int.

A signed long * signed long is still an signed long and can suffer from signed integer overflow, which is UB. The range of your signed long is less than the mathematical product of 0x12345678 * 0x12345678. By using ULL suffix, the math is done at least with unsigned long long math. @BLUEPIXY

printf("%llu\n", 0x12345678ULL * 0x12345678);
// or if the constant can not be changed
printf("%llu\n", 1ULL * SOME_BIG_CONSTANT * SOME_BIG_CONSTANT);

Pedantic note: When printing integer types that might wider than int/unsigned, insure the final computed result matches the specifier. Consider that SOME_BIG_CONSTANT might be wider than unsigned long long. Or leave the cast off, and cope with the potential compiler warning.

printf("%llu\n", (unsigned long long) (1ULL * SOME_BIG_CONSTANT * SOME_BIG_CONSTANT));

See also Why write 1,000,000,000 as 1000*1000*1000 in C?
and There are reasons not to use 1000 * 1000 * 1000

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256