View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
Does switch statement has a variable size limit? |
Posted: Mon May 17, 2021 11:06 am |
|
|
I'm trying to create a new subroutine that must select between values of a 32bit unsigned integer but when the case is bigger than 65536 I get an error.
"Constant out of the valid range 2097152 is not less than 65536"
My CCS V5.091 and MPLAB 8.92
Device PIC18F67J50
Example:
Code: | unsigned int8 TestKey(unsigned int32 KeyX)
{
switch(KeyX)
{
case 1: return 8;
case 4: return 14;
case 0x800000: return 15;//ERROR HERE
}
}
|
_________________ Electric Blue |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 17, 2021 1:10 pm |
|
|
CCS vs. 5.103 gives this error:
Quote: | Constant out of the valid range 8388608 is not less than 65536 |
This implies the case values must be no greater than 0xFFFF.
If I try to use 0x10000, it gives an error. |
|
![](templates/subSilver/images/spacer.gif) |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon May 17, 2021 1:47 pm |
|
|
So, I should use an if statement or split the int32 into two int16 and evaluate them in a separate switch if the value is higher than 0xFFFF. _________________ Electric Blue |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon May 17, 2021 5:50 pm |
|
|
Have you looked at the code that a switch statement generates? If you need that many switch branches - the serial code execution cycles alone are gonna crush you in the time domain for numinous arguments values, depending on the order of comparison. if you don't need a full deck of 32 bit compares consider a LUT to a smaller compare space and map your 32 bit code bits to that. But if this is linear collection of 32 bit values WTF ? You really don't care about execution speed or code bloat? Don't you have a better way to do what you want to do using indexed vars ? This feels a like C question more than a PIC one. |
|
![](templates/subSilver/images/spacer.gif) |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon May 17, 2021 7:54 pm |
|
|
The branches are not that many, just about 20; but the variable can have 2^24 different values.
Anyway, I solved as mentioned above. _________________ Electric Blue |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue May 18, 2021 12:29 am |
|
|
That is actually a 'C' limitation.
Historically CCS originally had a limit using an int8, and 256 cases.
ANSI C recommended that systems should support 1023 cases or more,
(from C89), and CCS later expanded the compiler to support int16's for the
case.
However int16, not int32's!.....
A few C's (very few, but MicroSoft in particular), don't have this limitation. |
|
![](templates/subSilver/images/spacer.gif) |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue May 18, 2021 1:18 am |
|
|
I don't need 1023+ branches, I need that the switch statement handle a 32 bit case variable and just 20 branches.
Anyway, thanks for the info. _________________ Electric Blue |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue May 18, 2021 1:40 am |
|
|
The case limit is a limit on the size of what is tested, not just the actual
cases used.
However I have to say that in your 'case', it'd actually probably be much
more efficient to just test for the values yourself (after all something
like 20 cases is a very simple number of tests). Doing a split and then using
two switches on part of the range, just adds complexity to the code, and
will probably be slower and bulkier than just testing.
Consider just something like a macro:
Code: |
#define LOOK_FOR(x) if (x==KeyX)
//Then just use:
LOOK_FOR(1)
return 8;
LOOK_FOR(4)
return 14;
LOOK_FOR(0x800000)
return 15;
|
|
|
![](templates/subSilver/images/spacer.gif) |
|