EmbeddedRelated.com
Forums

IAR weird signed long long behavior

Started by Gabriel July 20, 2006
Hello everyone

I tried this simple code in IAR

---------
void main(void)
{
signed long long myvar;

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

myvar = 948125391;

if (myvar > 2147483647) myvar = 2147483647;
else if (myvar < -2147483648) myvar = -2147483648;

for(;;)
}
---------

For some reason IAR fails in the (myvar < -2147483648) test and sets
the new value to myvar.
myvar is correctly allocated R15:R14:R13:R12 registers and the first
test works ok. Am I missing something here? (I would bet it's
something VERY simple :)
I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
(3.41.1.1), and 64-bit double type for this project.

gcalin

Beginning Microcontrollers with the MSP430

----- Original Message -----
From: "Gabriel"
To:
Sent: Thursday, July 20, 2006 9:15 PM
Subject: [msp430] IAR weird signed long long behavior
> Hello everyone
>
> I tried this simple code in IAR
>
> ---------
> void main(void)
> {
> signed long long myvar;
>
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
>
> myvar = 948125391;
>
> if (myvar > 2147483647) myvar = 2147483647;
> else if (myvar < -2147483648) myvar = -2147483648;
>
> for(;;)
> }
> ---------
>
> For some reason IAR fails in the (myvar < -2147483648) test and sets
> the new value to myvar.
> myvar is correctly allocated R15:R14:R13:R12 registers and the first
> test works ok. Am I missing something here? (I would bet it's
> something VERY simple :)
> I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
> (3.41.1.1), and 64-bit double type for this project.

I don't know what you need for a long long but it will be something like
2147483647L.

Leon

----- Original Message -----
From: "Leon Heller"
To:
Sent: Thursday, July 20, 2006 9:32 PM
Subject: Re: [msp430] IAR weird signed long long behavior
> ----- Original Message -----
> From: "Gabriel"
> To:
> Sent: Thursday, July 20, 2006 9:15 PM
> Subject: [msp430] IAR weird signed long long behavior
>> Hello everyone
>>
>> I tried this simple code in IAR
>>
>> ---------
>> void main(void)
>> {
>> signed long long myvar;
>>
>> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
>>
>> myvar = 948125391;
>>
>> if (myvar > 2147483647) myvar = 2147483647;
>> else if (myvar < -2147483648) myvar = -2147483648;
>>
>> for(;;)
>> }
>> ---------
>>
>> For some reason IAR fails in the (myvar < -2147483648) test and sets
>> the new value to myvar.
>> myvar is correctly allocated R15:R14:R13:R12 registers and the first
>> test works ok. Am I missing something here? (I would bet it's
>> something VERY simple :)
>> I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
>> (3.41.1.1), and 64-bit double type for this project.
>
> I don't know what you need for a long long but it will be something like
> 2147483647L.

I think it should be 2147483647q for a long long, it is in Objective C.

Leon
or (long long)2147483647

Manfred, Ulm

Leon Heller schrieb:
>
> ----- Original Message -----
> From: "Gabriel" >
> To: >
> Sent: Thursday, July 20, 2006 9:15 PM
> Subject: [msp430] IAR weird signed long long behavior
>
> > Hello everyone
> >
> > I tried this simple code in IAR
> >
> > ---------
> > void main(void)
> > {
> > signed long long myvar;
> >
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> >
> > myvar = 948125391;
> >
> > if (myvar > 2147483647) myvar = 2147483647;
> > else if (myvar < -2147483648) myvar = -2147483648;
> >
> > for(;;)
> > }
> > ---------
> >
> > For some reason IAR fails in the (myvar < -2147483648) test and sets
> > the new value to myvar.
> > myvar is correctly allocated R15:R14:R13:R12 registers and the first
> > test works ok. Am I missing something here? (I would bet it's
> > something VERY simple :)
> > I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
> > (3.41.1.1), and 64-bit double type for this project.
>
> I don't know what you need for a long long but it will be something like
> 2147483647L.
>
> Leon
>
>
I believe the compiler automatically casted 2147483647 to a long long
type, since I'm comparing it to a long long variable. I tried anyway to
add the 'L' and even explicit cast the constant... the test still failling.
I checked at the asm code and the test routine is using all 4 registers
(so I guess it's dealing with my long long variable). I still didn't
figure out what the asm algorithm is doing there. Wonder if it is a
compiler bug...

gcalin

Leon Heller wrote:
>
> ----- Original Message -----
> From: "Gabriel" >
> To: >
> Sent: Thursday, July 20, 2006 9:15 PM
> Subject: [msp430] IAR weird signed long long behavior
>
> > Hello everyone
> >
> > I tried this simple code in IAR
> >
> > ---------
> > void main(void)
> > {
> > signed long long myvar;
> >
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> >
> > myvar = 948125391;
> >
> > if (myvar > 2147483647) myvar = 2147483647;
> > else if (myvar < -2147483648) myvar = -2147483648;
> >
> > for(;;)
> > }
> > ---------
> >
> > For some reason IAR fails in the (myvar < -2147483648) test and sets
> > the new value to myvar.
> > myvar is correctly allocated R15:R14:R13:R12 registers and the first
> > test works ok. Am I missing something here? (I would bet it's
> > something VERY simple :)
> > I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
> > (3.41.1.1), and 64-bit double type for this project.
>
> I don't know what you need for a long long but it will be something like
> 2147483647L.
>
> Leon
>
>



Leon Heller wrote:
>>I don't know what you need for a long long but it will be something like
>>2147483647L.

No, that's just long.

> I think it should be 2147483647q for a long long, it is in Objective C.

It isn't standardised in C, I believe. gcc and MSVC use "ll" or "LL"
on the end of the digits.
Maybe you should also write :
for(;;);
instead of
for(;;)

The code will either restart, or exit the main() function.

-- Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of Gabriel Calin
Sent: Friday, 21 July 2006 6:44 AM
To: m...
Subject: Re: [msp430] IAR weird signed long long behavior

I believe the compiler automatically casted 2147483647 to a long long
type, since I'm comparing it to a long long variable. I tried anyway to
add the 'L' and even explicit cast the constant... the test still failling.
I checked at the asm code and the test routine is using all 4 registers
(so I guess it's dealing with my long long variable). I still didn't
figure out what the asm algorithm is doing there. Wonder if it is a
compiler bug...

gcalin

Leon Heller wrote:
>
> ----- Original Message -----
> From: "Gabriel" >
> To: >
> Sent: Thursday, July 20, 2006 9:15 PM
> Subject: [msp430] IAR weird signed long long behavior
>
> > Hello everyone
> >
> > I tried this simple code in IAR
> >
> > ---------
> > void main(void)
> > {
> > signed long long myvar;
> >
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> >
> > myvar = 948125391;
> >
> > if (myvar > 2147483647) myvar = 2147483647;
> > else if (myvar < -2147483648) myvar = -2147483648;
> >
> > for(;;)
> > }
> > ---------
> >
> > For some reason IAR fails in the (myvar < -2147483648) test and sets
> > the new value to myvar.
> > myvar is correctly allocated R15:R14:R13:R12 registers and the first
> > test works ok. Am I missing something here? (I would bet it's
> > something VERY simple :)
> > I'm using IAR C/C++ Compiler for MSP430 V3.41A/W32 [Evaluation]
> > (3.41.1.1), and 64-bit double type for this project.
>
> I don't know what you need for a long long but it will be something like
> 2147483647L.
>
> Leon
>
>
Just added the 'll' and the correct code was generated. However I didn't
understand why the compiler didn't generate the correct code in first
place (without the long long 'll' suffix). I always thought C compilers
automatically widen constants, var, etc, to the largest type in the
expression, unless you explicit cast them with a different type. Isn't
it right?
Thank everyone for the tips.

gcalin

Clifford Heath wrote:
>
> Leon Heller wrote:
> >>I don't know what you need for a long long but it will be something
> like
> >>2147483647L.
>
> No, that's just long.
>
> > I think it should be 2147483647q for a long long, it is in Objective C.
>
> It isn't standardised in C, I believe. gcc and MSVC use "ll" or "LL"
> on the end of the digits.
>
>



--- In m..., Gabriel Calin wrote:
>
> Just added the 'll' and the correct code was generated. However I
didn't
> understand why the compiler didn't generate the correct code in first
> place (without the long long 'll' suffix). I always thought C compilers
> automatically widen constants, var, etc, to the largest type in the
> expression, unless you explicit cast them with a different type. Isn't
> it right?

It does and it did. It's that the numbers weren't what you thought
they were.

Your original constant was an int. A compiler can warn you that
you have too many digits to fit in an int but I don't believe it's
required to.

The compiler then takes that int (with the wrong number) and
widens it in the expression.

It's similar to

double f;

f = 2/3;

assigning 0.9 to f.
A good lint (I personally like PC-Lint) is good at catching this class
of errors.

Robert

>double f;
>f = 2/3;
>assigning 0.9 to f.

Please expand on this...