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 support@ccsinfo.com

Is this a bug? It certainly got me

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



Joined: 09 Jul 2004
Posts: 10

View user's profile Send private message

Is this a bug? It certainly got me
PostPosted: Wed Jul 14, 2004 9:45 am     Reply with quote

Hello,

I'm an infrequent C programmer, and I realise that the use of string constants in CCS C is a no go. During the process of learning this I experienced some mighty strange behaviour. I've condensed the code to show it simply - Look at this:
Code:
#include <16F877.h>

#device ICD=TRUE


#fuses XT,WDT,PUT,NOBROWNOUT
#use delay(clock=4000000, restart_wdt)
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7, RESTART_WDT)

void send_id(char id[10])
{
   printf(id);
   // Why is the following line executed the same number of times as there are characters in the call to send_id()?
   delay_ms(1000);
}

void main() {
   setup_counters(RTCC_INTERNAL, WDT_18MS);

   // Now for the main loop
   do
  {
     send_id("1234567890");
   } while (true); // Stay in the loop forever
}

I have read the manual where it says:
Quote:
A (non-standard) feature has been added to the compiler to help get around the problems created by the fact that pointers cannot be created to constant strings. A function that has one CHAR parameter will accept a constant string where it is called. The compiler will generate a loop that will call the function once for each character in the string.

But, why does it call the delay_ms(1000) each time as well? I would argue that my function doesn't have a single CHAR, but an array of 10 CHARs. So, it would be nice if the compiler picked this up, and spat out an error (or a warning?) The CCS statement is ambiguous, I think?

I don't like this behaviour at all - It caused me a lot of head scratching! Is it worth reporting this to CCS, or am I missing something obvious?! I suspect that there are a number of people for whom improved string constant handling within PICC would make life much easier?!

Thanks for reading

Steve.
Futureatwork
Guest







PostPosted: Wed Jul 14, 2004 11:03 am     Reply with quote

If my understanding is correct, the function that will be called many times is send_id, once for each char...
Try to move the delay_ms to main loop right after the send_id call.
Guest








PostPosted: Wed Jul 14, 2004 11:21 am     Reply with quote

Try to use
void send_id(char *id)
Additionally your declaration is wrong: the input string is 11 byte long (10 characters + the terminating zero)
Guest








Re: Is this a bug? It certainly got me
PostPosted: Wed Jul 14, 2004 3:29 pm     Reply with quote

SteveC wrote:
Hello,
printf(id);



It would be program style if you declared your constants elsewhere.

const char ID[]={"1234567890");

Compiler takes care of figuring out how much space to allocate, and it takes care of adding the null also.

Then when you need to send the const string, try

puts(ID);

puts() will handle a const string. puts(0 adds cr/lf

If you only want the string without cr/lf the use a loop with putchar() .
Steve H.
Guest







PostPosted: Wed Jul 14, 2004 6:09 pm     Reply with quote

This is not a bug - but when you think about it it works exactly like it says it will. Look how CCS declares putc() then write a small program the sub's putc for your function. putc will be called as many times as needed to write the string - Actually this ia a very useful feature of the compiler and has saved me a bunch of time coding up a similar function myself many times.

I agree with guest. Your declarations are wrong, you should check out the declerations and how putc does it.


Steve H.
SteveC



Joined: 09 Jul 2004
Posts: 10

View user's profile Send private message

PostPosted: Thu Jul 15, 2004 3:13 am     Reply with quote

Thanks for the comments. The program I posted was merely to show the issue in the simplest way possible - It's not the program I'm writing. I actually need to call send_id with a variable, not a constant (the device uses a matrix keypad for id entry which is sent out of the serial port).

I can't use puts, as the CR/LF at the end will mess things up.

I agree that it's a very useful feature - It's just that I didn't know about it! I now understand how it works! (CCS do say that it's a non-standard feature, though!)

I could do it by calling putc from main, and then calling my verify function straight after it, instead of what I was trying to do initially which was to have the send_id function sending and verifying. In fact, I've declared 'id' as a global, so it's no longer an issue.

Steve.
Ttelmah
Guest







PostPosted: Thu Jul 15, 2004 5:23 am     Reply with quote

SteveC wrote:
Thanks for the comments. The program I posted was merely to show the issue in the simplest way possible - It's not the program I'm writing. I actually need to call send_id with a variable, not a constant (the device uses a matrix keypad for id entry which is sent out of the serial port).

I can't use puts, as the CR/LF at the end will mess things up.

I agree that it's a very useful feature - It's just that I didn't know about it! I now understand how it works! (CCS do say that it's a non-standard feature, though!)

It's now a simple matter of calling putc from main, and then calling my verify function straight after it, instead of what I was trying to do initially which was to have the send_id function sending and verifying.

Steve.

The 'key' is to understand what happens in main.
The 'send_id' fuction is reached, and a string of constant characters detected. The compiler then automatically switches to the 'fallback' behaviour to handle these, and calls send_id ten times, handing it one character in turn each time. Hence, 'of course' the delay inside the routine is called ten times. If the error checking in the compiler was better there would be a complaint at this point (since a function, that is expecting an 'address' for an array, instead receives a single character). However since the function itself then does nothing with this, except hand the character 'on' to printf, there is no error.
The function is behaving exactly as CCS says it should.
CCS is very 'liberal' about not reporting 'type' errors (which would at least warn you that the layout is wrong), hence it is common practice to run the code through a seperate C 'syntax checker', which will report this as an error, and avoid wasting time. However given the special exemption present in CCS C for this type of construction, such checkers will report the perfectly good construction as 'wrong', leaving it to you to detect the difference between the allowable form, and this mistake...

Best Wishes
bennyboos



Joined: 17 Nov 2005
Posts: 30
Location: Chester UK

View user's profile Send private message

Syntax Checker recommendations
PostPosted: Thu Dec 21, 2006 7:18 am     Reply with quote

Hi Ttelmah,
do you use a syntax checker and if so can you recommend one?
I've recently wasted a day with a very frustrating error whereby I was trying to compare a variable for negativity. My problem was that I had forgotten Embarassed to declare it as signed (see below) and this made it rather eratic in its behaviour.
Code:

int16 angle;
// ....
// other lines of code
// ....
do {
// ... other stuff
  refreshAngle(&angle);
} while(angle<0);

Can you suggest a tool/s that will spot this type of boo boo?

Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 21, 2006 10:51 am     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=17885&highlight=lclint
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