I'm doing a project using the Microchip C18 compiler. I have a struct called a block that points to other blocks (north east south west). These blocks will make me a map. I then have a pointer that I use to evaluate everything.
Just using RAM it looks like:
struct block{
struct block *north;
struct block *east;
struct block *south;
struct block *west;
};
struct block map[5] =
{ // just a simple line.
{ NULL, &map[1], NULL, NULL },
{ NULL, &map[2], NULL, &map[0]},
{ NULL, &map[3], NULL, &map[2]},
{ NULL, &map[4], NULL, &map[3]},
{ NULL, NULL, NULL, &map[4]}
};
struct block* position = &map[0];
This lets me do stuff like:
void goWest()
{
if(position -> west != NULL) position = position -> west;
}
Problem is that I've run out of RAM in my project and need to use ROM What I have so far is:
struct block{
rom struct block *north;
rom struct block *east;
rom struct block *south;
rom struct block *west;
};
rom struct block map[5] =
{ // just a simple line.
{ NULL, &map[1], NULL, NULL },
{ NULL, &map[2], NULL, &map[0]},
{ NULL, &map[3], NULL, &map[2]},
{ NULL, &map[4], NULL, &map[3]},
{ NULL, NULL, NULL, &map[4]}
};
I've done some debugging and can tell the above part works, but trying to make the position pointer is giving me grief. so I guess my question is:
How do I hold the ROM variable addresses in a pointer which I can edit the values of?
When i try:
struct block *position = &map[0];
I get "Warning [2066] type qualifier mismatch in assignment"
I realize that a ROM variable and RAM variable are two different things, but I have no idea what to do.
What is the definition of the rom
macro? I'm guessing that it expands to const
(and possibly a compiler-specific __attribute__
or somesuch), because the compiler is complaining about a "type qualifier mismatch", which refers to a const
or volatile
mismatch.
What that means is that you're trying to implicitly cast a pointer to constant data into a pointer to non-constant data. This code should generate the same warning with your compiler:
const int x = 0;
int *y = &x; // &x is "pointer to const" but y is "pointer to non-const"
To fix it, you need to declare that your position
pointer is a pointer to constant data (which, depending on the definition of the rom
macro, should be done with either rom
or the const
qualifier):
// Declare a non-constant pointer to constant data
const struct block *position = &map[0];
At each pointer level, you can have a const
qualifier or lack thereof, and likewise for the base non-pointer object. So, a single-level pointer can have 4 different variants:
int *x; // Non-constant pointer to non-constant data
int *const x; // Constant pointer to non-constant data
const int *x; // Non-constant pointer to constant data
int const *x; // Same as above
const int *const x; // Constant pointer to constant data
int const *const x; // Same as above
Note that int const
and const int
are equivalent, but otherwise the placement of const
does matter.