This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430G2553: Compiler misbehavior?

Part Number: MSP430G2553


Tool/software: Code Composer Studio

If in an MSP430 C program I declare

unsigned long dummy = 200000;

the compiler handles the declaration properly and assigns dummy the value 200000.

But if  I declare

unsigned long dummy = 100 * 2000;

the compiler assigns dummy the value 3392, which is 200000 - 3 * 2^16.

Shouldn't the compiler recognize that dummy has been declared unsigned long and compute the product to thirty-two bits?

  • The type of a constant depends on the value.  Once that is determined, the usual arithmetic conversions are used.  The same conversions are used regardless of whether the expression being evaluated is all constants, all variables, or a mix.  So, I'll annotate your expressions with casts that show the type of each constant.

    unsigned long dummy = (long) 200000;
    unsigned long dummy = (int) 100 * (int) 2000;

    Now, add in more casts, and some parenthesis, to show how the usual arithmetic conversions are applied.

    unsigned long dummy = (unsigned long) ((long) 200000);
    unsigned long dummy = (unsigned long) ((int) 100 * (int) 2000);

    The key is to notice that the multiply expression is done with type int.  On MSP430, this means 16-bit wide math.  When a signed expression like this overflows the type used to evaluate it, that is undefined behavior.  That is, the compiler can presume it will never occur.  Again, this is the case whether the expression is all constants or not.  

    The usual fix is to change the constants to type long with the suffix L.

    unsigned long dummy = 100L * 2000L;

    Thanks and regards,

    -George

  • I believe the default Eclipse compiler should be smarter when initializing an unsigned long. The GCC compiler has no trouble with

    // test assigning the product of two ints to unsigned long
    #include <stdio.h>
    unsigned long dummy = 100 * 2000;

    int
    main() {
    printf("dummy is %ld.n", dummy);
    }

    and prints

    dummy is 200000.

  • PF9244 said:
    The GCC compiler has no trouble

    Because the size of int is 32-bits, and not 16-bits.

    Thanks and regards,

    -George