Domanda

Why do these programs produce different outputs?

Program 1:

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller * 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

Output:

Smaller = 2147483647

Bigger = smaller * 2 = -2


Program 2:

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller;
    bigger *= 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

Output:

Smaller = 2147483647

Bigger = smaller * 2 = 4294967294


My guess is that program 1 attempts to store the multiplication result in a temporary storage which is of the same size as int. So it overflows. Whereas, program 2, stores the multiplication result in the larger storage.

Am I correct?

Additionally, if I have made any grievous mistake in either of the programs, please let me know (because according to me, those programs compile perfectly)!

È stato utile?

Soluzione

smaller is an int, so is the literal 2. So their product is an int too. Since INT_MAX * 2 can't be represented by an int (by definition, pretty much), it overflows leading to undefined behavior.

If, however, you store the value in a long long, then, when performing the multiplication, default integer promotion (the "usual arithmetic conversion") happens. Now, if your long long can represent INT_MAX * 2, you will end up with something semantically equivalent with bigger = bigger * (long long)2, which works as expected.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top