Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Any idea what's happening here?

Status
Not open for further replies.

Pommie

Well-Known Member
Most Helpful Member
I have a project that uses an uint24_t or unsigned short long (as MPLABX calls it) and I was getting some strange behavior.
I did a simple test to check this with the following code,
int24.png

I assumed temp would contain 0xfffc but it appears that the upper byte has also been set to 0xff.
I get this warning which I assume has something to do with it,
warn.png

But I don't understand this warning.
I can fix the error by using a cast, temp=(uint24_t)0x3fff<<2;
However, I'm trying to understand what is happening. Note the variable is set to zero at startup.

Thanks,

Mike.
 
My guess: try prefixing the 2 with 0x

Logic: the immediate value 2 is being stored as a signed int; it's part in the shift is causing the result to be a signed int and a negative value.
When that is assigned to the uint24_t, the sign bit gets extended.
 
It's not the 2 being not hexadecimal. What I think is happening is the 0x3fff is being shifted left to be 0xfffc and then the sign is being extended into the 24 bit variable. I can fix it in two ways, make the constant long temp=0x3fffL<<2; or cast to uint24 temp=(uint24_t)0x3fff<<2; It was your bit about sign getting extended that made me realise. Thanks,

Mike.
BTW, both methods use the same amount of memory even though there is no optimization.
 
A little further information.
I have a union to access the various bits of the uint24_t,
Code:
typedef union{
    uint24_t i;
    struct{
        uint8_t byte0;
        uint8_t byte1;
        uint8_t byte2;
    };
    struct{
        uint16_t word;
        uint8_t nowt;
    };
}work_def;

This means I have 3 ways to get the variable to contain 0x3fff,
Code:
    work_def work;
    work.byte0=0xff;
    work.byte1=0x3f;
    work.byte2=0;
OR  
    work.i=0x3fffL;
OR
    work.i=(uint24_t)0x3fff;
All work but the single byte version uses 2 extra words of program space.
Strange,

Mike.
 
For the sign to be extended, the result has to be signed. If the 2 isn't the cause, then it suggests that all hardcoded ints are treated as signed regardless of whether expressed in decimal or hex.
In which case the typecast of a hardcoded value to an unsigned int shouldn't cause any code generation; it should just be telling the compiler that is should treat the value as unsigned from the get go.

(I think. Its been a while.)
 
I have a project that uses an uint24_t or unsigned short long (as MPLABX calls it) and I was getting some strange behavior.
I did a simple test to check this with the following code,
View attachment 135495
I assumed temp would contain 0xfffc but it appears that the upper byte has also been set to 0xff.
I get this warning which I assume has something to do with it,
View attachment 135496
But I don't understand this warning.
I can fix the error by using a cast, temp=(uint24_t)0x3fff<<2;
However, I'm trying to understand what is happening. Note the variable is set to zero at startup.

I seem to recall this was discussed a few months back?, something silly like XC8 converts unsigned to signed to do maths functions on them, then converts the answer back.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top