CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SWITCH-CASE bug with signed long on 5.026?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
benoitstjean



Joined: 30 Oct 2007
Posts: 566
Location: Ottawa, Ontario, Canada

View user's profile Send private message

SWITCH-CASE bug with signed long on 5.026?
PostPosted: Thu Oct 20, 2016 6:45 am     Reply with quote

Compiler: 5.026
Device: PIC24EP512GP806

Unless I misread or misunderstood something, I just tried a switch/case statement and the value being checked is a <signed long> and if I pass a negative value, it is ignored therefore I suspect the switch/case statement to only accept <unsigned int8> or has a bug?

Example:
Code:

void MyFunction( signed long MyValue )
{
    fprintf( SERIAL, "MyValue (Initial): %Ld", MyValue );

    switch( MyValue )
    {
        case -1:
        {
            fprintf( SERIAL, "MyValue (switch -1): %Ld", MyValue );
            // This case statement is not seen and is skipped
        }
        break;

        case 0:
        {
            fprintf( SERIAL, "MyValue (switch 0): %Ld", MyValue );
            // This case statement is seen
        }
        break;

        case 255:
        {
            fprintf( SERIAL, "MyValue (switch 255): %Ld", MyValue );
            // This case statement is seen when MyValue is -1
        }
        break;
     }
}

So in the above function, this is what I get as an output:

MyValue (Initial): -1
MyValue (switch 255): 255

In MyFunction, the values passed are #defines:
Code:

#define ValueNeg    -1
#define ValueZero    0
#define Value255     255

And if I replace the switch/case by a standard if statement, then it works.

Ben
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 7:14 am     Reply with quote

I don't know for sure what is, or isn't going on. One thing I do notice is: what do you think the size of "unsigned long" is on PIC24s with CCS? Hint: it is not the same as on 18/16/12s.

It would not surprise me that CCS C assumes expressions for switches are unsigned, as that is the default for int for many versions of the compiler. In other words, there may be a "hangover" from other implementations of the compiler. It would surprise me that int8 was the only acceptable size. I am pretty sure sixteen bit values can be used in switches. I'm not convinced about 32 bit values, hence my comment above.

Switches are not implemented the same way in all cases, it depends a lot on the type of the selector variable and on the number of cases, and on whether there is a default or not. In some cases a switch will be implemented in much the same way as a if-ladder, sometimes by a jump table and sometimes by other means.

Also, I not at all sure that all types would be acceptable in switches. For example I am not at all sure how floats would behave when used aas the selector. I assume a bit for bit comparison is used (or effectively so), so provided floats were normalised there shouldn't be a problem... should there? Even so, I would not recommend float selectors, and regard it a "bad form" and derogate it as a programming practise, much as we do in precise float comparisons.


Last edited by RF_Developer on Thu Oct 20, 2016 7:20 am; edited 1 time in total
benoitstjean



Joined: 30 Oct 2007
Posts: 566
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 7:17 am     Reply with quote

Fair enough. Anyhow I just thought I'd post it here in case anyone else runs into the same situation.

Since I am only evaluating 3 values, the good'old <if> statement works just fine.

Thanks.

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19557

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 7:37 am     Reply with quote

Are you sure you need an int32?.
On your compiler, the default integer is a signed iint16, and this is the default type used behind the switch statement.
Basically the test values are stored as and tested as int16 values.
It'll work if you cast your value to an int16 (avoid using 'long', since it has different meanings on different compilers - always much safer to be explicit on the sizes you use). So:

Code:

switch((signed int16) MyValue )


That the type used in switch is the default integer, is actually in the C standard. However CCS stretch it for the 8bit PIC's now and do accept int16.
benoitstjean



Joined: 30 Oct 2007
Posts: 566
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 8:35 am     Reply with quote

Ah! You are correct! I didn't realize that by using a 'long' I was using a 32-bit number. I changed it to a signed int16.

Thanks!

Ben
jeremiah



Joined: 20 Jul 2010
Posts: 1358

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 9:26 am     Reply with quote

As a point of interest, if you change your first case statement from -1 to some number larger than a 16 bit number (like 80000) it will generate a compiler error saying that the number is out of range. So this indicates (and reinforces what was said earlier) that the switch statement can only handle int16 sized or lower case values.
temtronic



Joined: 01 Jul 2010
Posts: 9249
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 9:40 am     Reply with quote

re:...
Quote:
the switch statement can only handle int16 sized or lower case values.

um, what about UPPER case values ?? LOL.

Hay, you made my day !
I KNOW what you meant, just funny to me 'lower case values'......

I'd have thought 'switch' vales had to be unsigned integers, say 16 bit max, in order to be fast to compare....

cheers

Jay
jeremiah



Joined: 20 Jul 2010
Posts: 1358

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 11:07 am     Reply with quote

Glad to bring some joy!

This thread also reminded me why our coding standards require us to use the sized types (int8, int16, int32) for numeric and raw data. Normally we ban the use of "long" and "int" unless there is a specific reason to use them.
Ttelmah



Joined: 11 Mar 2010
Posts: 19557

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 1:30 pm     Reply with quote

Signed makes no difference to the compare. -1 (int16) codes as 0xFFFF, and it is this that the test compares to.
Agree wholeheartedly with Jeremiah. Once you move between different processors and languages, being 'explicit' on sizes become essential. Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group