Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Thread Tools Display Modes
Old 14th March 2008, 12:49 AM   (permalink)
Default C30 pointer warning - should be legal, but why the warning?

Here's the part of the code in question (with some irrelevant lines left out):
Code:
void lcd_string(char *);

char sentence[16] = "dsPIC 30F4013";

int main(void)
{
	lcd_string(&sentence);			//send string to LCD
	for(;;){}						//spin forever
	return 0;
}

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}
Now why does MPLAB/C30 give me this warning?
Quote:
lcd_4bit_2.c:38: warning: passing argument 1 of 'lcd_string' from incompatible pointer type
According to O'Reilly's Practical C Programming that's the way to do it.

It seems to work anyway, but I always like to get rid of warnings if possible.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 12:52 AM   (permalink)
Default

I believe that because the argument to LCD_String is a char pointer, it is expecting a char pointer as an argument and not some number (even if it is an address). I think the error would go away if you had actually declared "sentence" as a char pointer, place your data at that memory location, and used it as an argument instead.

It is probably unable to figure out whether or not the address given corresponds to the proper memory reserved for a character.

But who cares about warnings anyways. THe software isn't smarter than you are. It could come up with 40 warnings that don't matter because it's a dumb piece of software searching for certain criteria in your code.

Last edited by dknguyen; 14th March 2008 at 12:56 AM.
dknguyen is offline   Reply With Quote
Old 14th March 2008, 01:00 AM   (permalink)
Default

Quote:
Originally Posted by dknguyen
I believe that because the argument to LCD_String is a char pointer, it is expecting a char pointer as an argument and not some number (even if it is an address).
But a char pointer IS a number!

Quote:
I think the error would go away if you had actually declared "sentence" as a char pointer, place your data at that memory location, and used it as an argument instead.
I'm confused. "sentence" is a plain-jane char array. I pass its address to lcd_string as a pointer to the array. How could the compiler not understand that?

And how can I put my array in a char pointer? That makes no sense (to me at least).
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 01:08 AM   (permalink)
Default

I think I kinda get what you're trying to say. I rewrote it like this and the warning is gone. And the code even works!
Code:
void lcd_string(char *);

char sentence[16] = "dsPIC 30F4013";

int main(void)
{
	char *senpoint = sentence;
	lcd_string(senpoint);			//send string to LCD
	for(;;){}				//spin forever
	return 0;
}

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 02:25 AM   (permalink)
Default

Does the compiler whine if you do this:
lcd_string(sentence);
OR
lcd_string(&sentence[0]);
__________________
--- The days of the digital watch are numbered. ---
kchriste is offline   Reply With Quote
Old 14th March 2008, 02:33 AM   (permalink)
Default

Quote:
Originally Posted by kchriste
Does the compiler whine if you do this:
lcd_string(sentence);
That works fine. No warnings. I like this one. Simple, clear and uncluttered.

Makes sense too. After all, sentence IS a pointer to the start of the string. I'm (re)learning...

Quote:
lcd_string(&sentence[0]);
That too. No warnings.

Heh! More than one way to skin a cat.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 14th March 2008 at 02:38 AM.
futz is online now   Reply With Quote
Old 14th March 2008, 02:47 AM   (permalink)
Default

Yeah, what I meant was the a pointer has the address as well as the number of memory locations following that address that belong to the pointer, while an address is just an address without the reserved memory information. It was this extra information that the compiler could not match up to with the argument that was declared as a pointer.

Code:
char sentence[16] = "dsPIC 30F4013";
char *senpoint = sentence; //this makes the pointer equal to the address of the first character of "sentence"

//you can also make an array of of pointers
char *senpoint[] = "dsPIC 30F4013" //array size calculated implicitly from string length
char *senpoint[13] = "dsPIC 30F4013" //array size calculated explicity but must match string length
With the array, it is like producing a pointer for each letter in the string and placing all the pointers in an array.

Last edited by dknguyen; 14th March 2008 at 02:55 AM.
dknguyen is offline   Reply With Quote
Old 14th March 2008, 02:54 AM   (permalink)
Default

Quote:
Originally Posted by dknguyen
Yeah, what I meant was the a pointer has the address as well as the number of memory locations following that address that belong to the pointer, while an address is just an address without the reserved memory information. It was this extra information that the compiler could not match up to with the argument that was declared as a pointer.
Oh really? I always understood that a pointer was just an address, and nothing more. Really that is all I as a programmer should have to know anyway. What the compiler does internally shouldn't be generating warnings on perfectly legal code. But what do I know? I'm a rank newb at C again.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 02:59 AM   (permalink)
Default

Nope. That's the reason you don't just have a single pointer for everything and why pointers have different data types like int pointers, char pointers, float pointers, double pointers THe data type tells the pointer how much memory is associated with it (the same number of bytes associated with the data type).

It is more important for commands for real C++ like new and delete which reserve areas of memory based for the pointer they are given.
dknguyen is offline   Reply With Quote
Old 14th March 2008, 02:59 AM   (permalink)
Default

Ah! So if I had done this
Quote:
char *senpoint[] = "dsPIC 30F4013"
my original method would have generated no warning?

I'm starting to grok it now, maybe... It's all about memory management.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 03:00 AM   (permalink)
Default

Quote:
Originally Posted by futz
Ah! So if I had done this

my original method would have generated no warning?

I'm starting to grok it now, maybe...
I *think*. It's been a while since anything substantial in C/C++. Try it out. I could it look it up in my book, but it's like 4 feet away from me. Compared to declaring the variable and then making a pointer to it, tHe difference is that you only have a pointer to refer to the string and no variable name.

Last edited by dknguyen; 14th March 2008 at 03:03 AM.
dknguyen is offline   Reply With Quote
Old 14th March 2008, 03:05 AM   (permalink)
Default

Quote:
Originally Posted by dknguyen
Try it out.
Tried. It warns on this:
Code:
char sentence1[] =  "dsPIC 30F4013  ";

	lcd_string(&sentence1);
but is happy with this:
Code:
char sentence1[] =  "dsPIC 30F4013  ";

	lcd_string(sentence1);
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is online now   Reply With Quote
Old 14th March 2008, 03:09 AM   (permalink)
Default

Now you now! (and so do I).

It's almost like the difference between saying:

char var1 = 0x61;

and

char var1 = 'a';

It would probably cause a warning because the datatypes are different/unexpected even though the information carried is the same. (But I think a compiler might reject this outright.)

EDIT:
Code:
char senpoint[] = "dsPIC 30F4013" 

//is the same as

char *senpoint[] = "dsPIC 30F4013"
Because an array of chars, ints, or anything else is actually a pointer to the first character of the array (with some additional data about the number of elements in the array which are arranged consecutively in memory after the pointer), rather than an array of chars, int, or other regular variable type. That is why you can go
Code:
char sentence1[] =  "dsPIC 30F4013  ";
and not have
Code:
lcd_string(sentence1);
complain that sentence1 is not a pointer. Just thought I'd let you know in case you accidentally left out the * in the array declaration and were suprised that it worked.

Last edited by dknguyen; 14th March 2008 at 03:20 AM.
dknguyen is offline   Reply With Quote
Old 14th March 2008, 03:33 AM   (permalink)
Default

The reason it warns on lcd_string(&sentence1); is because the & is being used as the address of operator. So when you type &sentence1 you are saying the Address of the pointer sentence1. Essentially you are giving a pointer to a pointer so the compiler balks because your lcd_string routine wants the actual pointer.
The reason lcd_string(&sentence1[0]) works is because sentence1[0] returns the character at index 0 in the array sentence1. Adding the & just returns the address of character at index 0 which is at the start of the array sentence1 so we end up with a pointer to the array sentence1.
__________________
--- The days of the digital watch are numbered. ---

Last edited by kchriste; 14th March 2008 at 03:36 AM.
kchriste is offline   Reply With Quote
Old 14th March 2008, 03:33 AM   (permalink)
Default

Quote:
Originally Posted by dknguyen
Just thought I'd let you know in case you accidentally left out the * in the array declaration and were suprised that it worked.
My code hasn't ever had the * on the array declaration. Here's what it looks like at present (this obviously isn't all of it). Works good :
Code:
char sentence1[] = "dsPIC 30F4013  ";
char sentence2[] = "Two UARTs      ";
char sentence3[] = "Four 16-bit PWM";
char sentence4[] = "33 interrupts  ";

int main(void)
{
	ADPCFG = 0xffff;			//all digital
	TRISA = 0;				//PORTs all outputs
	TRISB = 0;
	TRISC = 0;
	TRISD = 0;
	RW = 0;					//set R/W low
	E = 0;					//set E low
	lcd_busy();				//wait for LCD to settle
	lcd_init();
	
	while(1)
	{
		lcd_line1();
		lcd_string(sentence1);		//send string to LCD
		lcd_line2();
		lcd_string(sentence2);
		delay();
		lcd_line1();
		lcd_string(sentence3);		//send string to LCD
		lcd_line2();
		lcd_string(sentence4);
		delay();
	}
	return 0;
}

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 14th March 2008 at 03:46 AM.
futz is online now   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes




All times are GMT. The time now is 12:05 AM.


Electronic Circuits  |  Electronics Wiki
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.