-
Levels of Indirection???
Every once in a while, I get this same warning message that causes DOS to crash and I don't know what to do about it. I'll give you the code, and then the warning:
Code:
#include <stdio.h>
char vName[] = "John Smith";
char *const pName = &vName;
char vDate[] = "9/10/01";
const char *pDate = &vDate;
int main()
{
printf("Name = %s Date = %s", *pName, *pDate);
*pName = "George Washington";
pDate = "6/10/01";
printf("Name = %s Date = %s", *pName, *pDate);
return (0);
}
That's the code. And the warning message is "'const char *' differes in levels of indirection". What exactly would a level of indirection be? Well, this warning is causing the program to crash and it is getting to me. Thanks.
-
Well there are quite a few broken indirections in your code.
Code:
char vName[] = "John Smith";
char *const pName = vName; // this is a constant pointer
char vDate[] = "9/10/01";
const char *pDate = vDate; // this is a pointer to a constant
int main()
{
printf("Name = %s Date = %s", pName, pDate);
pName = "George Washington"; // it's constant, so this assignment is illegal
pDate = "6/10/01";
printf("Name = %s Date = %s", pName, pDate);
return (0);
}
> What exactly would a level of indirection be?
It's a count of how many *'s you have to go through to get to the real data.
> Well, this warning is causing the program to crash and it is getting to me.
Fix the code then - this is one of the warnings you shouldn't be ignoring.
-
Well, I have just gotten a reply from another C message board and I think you two have different explanations. He said that I was trying set set a string to a pointer. The array of a pointer, he said, is memory so you can't set an array of characters to it. He said that I would have to do the strcopy function to put another string into it. Do you agree? I don't really understand what you are saying.
When you say the level of indirection is "a count of how many *'s you have to go through to get to the real data", what do you mean? Thanks.
-
I think I just realized something. When you say the number of *'s to get to the data, you mean the number of pointers, right? So, where was my error? I read that I can change the pointer to a constant string (for example) and that isn't working with the string, but the constant. Now that I think of it, it doesn't really make sense.
Take a look at my first post. So, you're saying if you have:
Code:
const char *pPointer = &vVar;
that I can't change either the pointer (pPointer = 'A') or I can't change what it points to (*pPointer = 'A')? Is there a difference between my two examples (pPointer = 'A' and *pPointer = 'A')? But if I have this:
Code:
char *const pPointer = &vVar;
then I can legally do the changes (pPointer = 'A' and *pPointer = 'A') because the const pointer only means that that pointer can only point to that char address, right? Thanks.
-
char vName[] = "John Smith";
char *pPointer = &vName;
Ignoring the const for a moment, this code has incompatible types.
An array name by itself (vName) has the same type as a pointer to any element of the array (&vName[x]), and specifically the same value as a pointer to the first element of the array (&vName[0]).
So you would have
char vName[] = "John Smith";
char *pPointer = vName;
The &vName is a pointer to the whole array, not a pointer to the first element (it's likely to be the same value as a pointer to the first element, but the type is totally different)
To make this valid, you need a different type of pointer
char hello[] = "hello";
char (*arr)[6] = &hello;
Note that this isn't an array of 6 pointers to char, its a pointer (singular) to an array of 6 characters.
The const keyword can be used as follows
char hello[] = "hello";
char world[] = "world"
const char *a = hello;
char * const b = hello;
a is a pointer to a constant char - this means you can modify a (say a=world), but you can't modify what a points to (say a[0] = 'f' would be illegal).
b is a constant pointer to char - this means you cannot change b, but you can change b[0]
const char * const c = hello;
means you cannot modify c or c[0]
> Do you agree?
No - what you are trying to do is perfectly valid, once you've sorted out some of the use of & and * in a place or two.
-
So, how come that my code was invalid? I had right syntax (I think). I had this:
Code:
char first[10];
const char *ptrfirst = &first;
char last[10];
char *const ptrlast = &last;
int main()
{
ptrfirst = "Thomas"; /* Is this legal? I'm changing the pointer, not the object it points to, right? */
*ptrlast = "Jefferson"; /* Is this legal? I'm changing the object that the pointer points to, not the pointer, right?
return (0);
}
Isn't this code right? If not, why? Thanks!
-
> const char *ptrfirst = &first;
Recall my previous post about the difference between first and &first.
The levels of indirection are the same, but the pointers are of an incompatible type
So
const char *ptrfirst = first;
> ptrfirst = "Thomas";
Nothing wrong here - ptrfirst is a (variable) pointer to a const char, so assigning the pointer to point to another char is valid.
"string" has the type const char *
So you have these types in the assignment.
const char * = const char *
so all is well
> *ptrlast = "Jefferson";
I get this - warning: assignment makes integer from pointer without a cast
What you're trying to do here is take a pointer (to the string), cast it to an integer and truncate it so it fits inside a single character.
You have these types in the assignment.
char = const char *
a char just being a small integer
If you tried this
> ptrlast = "Jefferson";
I get this - warning: assignment of read-only variable `ptrlast'
Althought the types match, you've said that ptrlast is a constant, so it complains when you try and modify the pointer.
To update this, you would need something like
strcpy( ptrlast, "Jefferson" );