View previous topic :: View next topic |
Author |
Message |
EdWaugh
Joined: 07 Dec 2004 Posts: 127 Location: Southampton, UK
|
Suffixes for constant literals in PCWH |
Posted: Fri Jan 27, 2012 4:02 am |
|
|
Hi all,
I was wondering if anyone could advise me on something I couldn't see in the CCS manual. I tend to declare constant literal values using #define rather than as const as I like the compiler to do some of the maths for me, there is a good discussion of this here:
http://www.ccsinfo.com/forum/viewtopic.php?t=41787&highlight=constant+literal
However, I can't find a list of correct suffixes for CCS, here's my guess:
Code: |
#define a (-20) // type = signed int 8 (actually ccs default to unsigned so I dunno what goes on here)
#define b 20u // type = unsigned int 8
#define c (-2000l) // type = signed int 16
#define d 2000ul // type = unsigned int 16
#define e (-200000ll) // type = signed int 32
#define f 200000ull // type = unsigned int 32
|
Suggestions or page numbers in the manual would be most welcome!
Cheers
Ed |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 27, 2012 4:35 am |
|
|
CCS, is standard C with regards to this. The only difference (which is also standard from the original C manual), is what the actual sizes mean. So an unsized literal smaller than 256, is by default an int8. Add 'L' (or 'l', but this is easier to mistake for a '1'), and it is a 'long', add 'F' and it is a float, even if no decimal point is present. There is no 'll' for a long double, but remember that any number too large to fit in an int8 is automatically an int16, and any number to large to fit into an int16, is _automatically_ an int32, also that while types will not automatically be promoted during the maths, unlike CCS's internal arithmetic, maths done at compile time _will_ carry to a larger type.
So:
Code: |
#define VAL1 (30000)
#define VAL2 (300)
int32 i32_silly=VAL1*VAL2;
|
Will put 9000000 into 'silly'
It is always good practice to bracket #defined constants generally (not just -ve values), and using capitals helps to distinguish them from variables.
Best Wishes |
|
|
EdWaugh
Joined: 07 Dec 2004 Posts: 127 Location: Southampton, UK
|
|
Posted: Fri Jan 27, 2012 5:54 am |
|
|
Hi Ttelmah,
Thanks very much for your response. I'm not sure I'm keen on letting the compiler decide the size of the value used in the calculation, surely it's better for me to define it?
Also, LL compiles with the CCS compiler which makes me think it does something. So I did a test:
Code: |
#define PSP_TEST_VAL (5LL)
fprintf(RS232A, "Size of: %u", sizeof(PSP_TEST_VAL));
|
This produces the output:
Size of: 4
Making me think it has correctly sized the value even tho it is small enough to fit in an int.
Thanks
Ed |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 27, 2012 7:29 am |
|
|
Fair enough, but undocumented.
Seriously, remember you can just cast a type explicitly. So
#define FRED ((int32)2)
is standard, documented, and ensures no surprises.
As you say LL appears to work, but I find it hard enough to trust documented features....
Best Wishes |
|
|
EdWaugh
Joined: 07 Dec 2004 Posts: 127 Location: Southampton, UK
|
|
Posted: Fri Jan 27, 2012 7:45 am |
|
|
Hi Ttelmah,
Yea I agree about the lack of documentation, but in your example isn't the underlying type still int8 and then it just gets cast to an int32? Maybe that doesn't matter really as I think it would always get used correctly. And maybe it's better as I guess my example should take four bytes in ROM where as yours should take only one?
Thanks
Ed |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 27, 2012 7:52 am |
|
|
A number is not 'stored' if it is a #define. The actual numeric value is substituted at compile time. The substituted value is the 4 byte representation of the number, the int8 form is not used anywhere.
Best Wishes |
|
|
|