Home > OS >  C: Undefined behavior when multiplying uint16_t?
C: Undefined behavior when multiplying uint16_t?

Time:09-05

I've realized and read that multiplying a uint16_t with another uint16_t results in an integer (it actually seems to be a signed integer? see: ). Given that, do I have to assume that the following function f produces undefined behavior, because there'll be a signed integer overflow?

The overflow would occur, because x*x for x=45000 results in "almost" INT32_MAX and it will then overflow if it is multiplied again by x.

(btw: on my platform int is a int32_t)

#include <stdio.h>
#include <stdint.h>

uint16_t f(uint16_t x) {
    printf("%zu\n", sizeof(x));     // <-- 2
    printf("%zu\n", sizeof(x * x)); // <-- 4
    return x * x * x;
}

int main()
{
    uint16_t x = 45000;
    uint16_t y = f(x);
}

The overflow would occur, because x*x for x=45000 results in "almost" INT32_MAX and it will then overflow if it is multiplied again by x.

Is this correct, or do I make some wrong assumptions?

CodePudding user response:

You are correct that your posted code will invoke undefined behavior due to signed integer overflow.

According to §6.3.1.1 ¶2 of the ISO C11 standard, the uint16_t operands will both get promoted to an int, because an int is 32-bits wide on your platform and therefore able to represent all values representable by uint16_t. If this were not the case, then the operands would get promoted to unsigned int.

Therefore, on platforms on which int is 32 bits wide, you will be getting a signed integer overflow (which is undefined behavior), whereas on platforms on which int is 16 bits wide, you will be getting an unsigned integer overflow (which is not undefined behavior).

  • Related