Potential problems with int type

Hello,

let’s say I have the following code:

uint32_t f(uint8_t a, uint8_t b) {
    int c = a - b;
    return c * c;
}

I think what happens here is that I take two unsigned 8 bit integers and store their difference in c, which is an int. Implicitly they should be converted into a signed integer (i.e. 32 bit or 64 bit) and then subtracted.
Upon return c * c the value is implicitly converted into an unsigned 32 bit integer. (and that is perfectly fine since the result is always positive, so no information is lost)

I tried figuring out whether something can go wrong if I were to run this on a 32 bit system as opposed to a 64 bit system. I think here it works out because the subtraction is “lossless” but if I had uint32_t as inputs (i.e. the type of a and b would be uint32_t instead) then the output would be incorrect on a 32 bit system.

If my thoughts so far are correct then why do people use int at all?

(I put this in the seam carving category as I am probably not the only one who did something similar in their code for the project)

I can not really follow your thoughts, but this is a great question nontheless. I would argue that not fixing the size of types was one of C’s greatest mistakes. IMHO, you should always use explicitly sized types, except in places where the problem statement says you don’t.

A binary operation on the same integer types does not perform a conversion by C99 standard 6.3.1.8 .
Therefore, the subtraction happens on uint8_t .

The cast to int is lossless and the same as the cast to an unsigned int as sizeof(int) >= 1.

As the integer contains a number that fits in a uint8_t the conversion to a uint32_t should not pose any problems.

The subtraction does not happen in uint8_t in my case. The following code:

    uint8_t a = 2;
    uint8_t b = 3;
    int x = a - b;
    printf("%d\n", x);

produces the output:

-1

while the code:

    uint8_t a = 2;
    uint8_t b = 3;
    uint8_t x1 = a - b;
    printf("%d\n", x1);
    int x = x1;
    printf("%d\n", x);

produces the output:

255
255

(tested in the VM)

In the first piece of code it seems like a and b are first converted to int and then subtracted (hence the -1) while in the second the calculation takes place modulo 256 and the result 255 is then transformed into the signed integer 255.

So what am I missing?

I think this is incorrect. If I read the corresponding part of the standard correctly:

So I think both operands should be promoted to int here (assuming int is big enough to represent all values of uint8_t)

1 Like

This is correct. The section is 6.3.1.1 of the C99 standard.
Integer promotion happens before conversion.
I was not careful enough while skimming over it.

1 Like

So that settles it. a - b is essentially (int)a - (int)b due to integer promotion of the uint8_t operands in the arithmetic expression. Afterwards, uint8_t x1 = a - b; corresponds to uint8_t x1 = (uint8_t) -1; which evaluates to 255.