Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

C30 pointer warning - should be legal, but why the warning?

Status
Not open for further replies.

futz

Active Member
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?
lcd_4bit_2.c:38: warning: passing argument 1 of 'lcd_string' from incompatible pointer type

According to O'Reilly's **broken link removed** that's the way to do it.

It seems to work anyway, but I always like to get rid of warnings if possible.
 
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:
dknguyen said:
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! :D

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).
 
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! :D
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++;
	}
}
 
Does the compiler whine if you do this:
lcd_string(sentence);
OR
lcd_string(&sentence[0]);
 
kchriste said:
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...

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

Heh! :D More than one way to skin a cat.
 
Last edited:
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:
dknguyen said:
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? :p I'm a rank newb at C again.
 
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.
 
futz said:
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:
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:
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.
 
Last edited:
dknguyen said:
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 :D :
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++;
	}
}
 
Last edited:
kchriste said:
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.
Oh!!! Now THAT makes sense to me. Now I get why it was warning me. The book was talking about int pointers, which threw me off.
 
kchriste said:
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.

Ah that makes sense...because an array is already a pointer! We've come full circle now.
 
because an array is already a pointer!

I think it is the language which has been confounding you :) If, instead, you say 'the name of the array is a pointer to the array,' rather than the array is a pointer. IE: 'array' contains the address of 'array[7]'
 
BeeBop said:
I think it is the language which has been confounding you :) If, instead, you say 'the name of the array is a pointer to the array,' rather than the array is a pointer. IE: 'array' contains the address of 'array[7]'
That part I already understood. :) It was the fact that I was making a pointer to a pointer that I was foggy on, and kchriste clarified that perfectly.
 
futz said:
That part I already understood. :) It was the fact that I was making a pointer to a pointer that I was foggy on, and kchriste clarified that perfectly.
I knew you and dknguyen both got it, but in dknguyen's post, he stated his understanding, which isn't quite correct in terms of the language he used, but which I'm he understands the meaning of.
Handles (pointers to pointers) are quite common when dealing with an OS which dynamically assigns memory and I think pointers and their arithmetic are the most difficult parts for anyone learning C; they are also one of the most useful abstractions in C.

BTW I'm watching what you're doing with these dsPICs, since I'll be spending some time with them in the not too distant future, so thanks for blazing the trail! :D
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top