|
|
View previous topic :: View next topic |
Author |
Message |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
Ternary operator with strings problem |
Posted: Mon Dec 13, 2010 6:21 pm |
|
|
Currently using compiler 4.114 with a PIC18F14K22 and ran into an issue in my code. I wanted to print either "ON" or "OFF" as part of the string to the LCD based on the HTR_pwr flag (int1) in my code so I tried to do it using the ternary operator ( condition ? if true : if false ) The code I used was:
Code: | printf(lcd_putc,"\fAIR=%Ld, HTR=%Ld\n",AIR_avg/10, HTR_avg/10);
printf(lcd_putc,"dT=%Ld Pw=%Lu %s",Tdelta, Pwidth, ((HTR_pwr==1) ? "ON":"OFF"));
|
Which compiles with no errors but when I run it, I get the first two results on the second line as expected for "dT" and "Pw", however, for the third field (declared in printf as a string with %s), what I get is a Pi symbol. Am I doing something not supported in the CCS compiler ? I had found several examples showing that basic construct via Google, however, this is not working as expected
Thanks !
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Dec 14, 2010 3:30 am |
|
|
I would not have expected this to work (though see comment below), but would have expected an error about attempting to create a pointer to a constant. The problem is a little 'hidden' one (a search here will find a _lot_ about it...), where the PIC has the ROM and RAM address spaces in different memory areas, so there are two 'address 100' locations, one in ROM, and one in RAM. Now, remember that a string is not a basic 'type' in C, so what you are doing here is constructing two arrays, and potentially returning the address of each. Given that "ON", is in ROM, how can the address be constructed....
CCS has a 'work round' for this, in a statement PASS_STRINGS=IN_RAM, which when it meets a constant string, should automatically copy it to RAM, and allow a pointer to be constructed there (at a cost in performance). So with this selected, the potential for working was present.
However it also has a huge number of other 'work rounds', with constant strings met in a printf, being automatically handled. What appears to be happening here, is that the ternary operator, is preventing this work round from working...
I must admit it is a construct that ought to work, with PASS_STRINGS=IN_RAM selected (it doesn't), and should be reported to CCS on this basis. Without this option, it is not really 'legal', and should return an error.
Obviously, you can get the same result (at a cost in elegance), by generating RAM copies of the strings required. So:
Code: |
char on[]="ON";
char off[]="OFF";
sprintf(output,"%s",((HTR_pwr==1) ? on:off));
|
I was 'hoping', that with the PASS_STRINGS option selected, it might work by explicitly casting - So:
(HTR_pwr==1) ? ((char *)"ON"):((char *)"OFF"))
But it still doesn't seem to work... :-(
So the answer is that on a 'bare' compiler running in the default configuration, I'd not have expected it to work, but even with an option selected that should make it work, it is not....
Best Wishes |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Tue Dec 14, 2010 12:30 pm |
|
|
OK, thanks - I was afraid it was something like that but also expected the compiler to complain if it didn't like it. Not a peep (other than to warn me that "while(1)" never exits in my main loop :-)
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
|
|
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
|