3

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.

1
  • Hi Cal Pratt, and welcome. I've done a few small edits on your text, you might want to take a look. Commented Nov 20, 2012 at 23:48

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The Microchip PIC uses a Harvard architecture -- ROM and RAM are in completely separate address spaces, so you can't mix pointers to the two. I believe they're using a custom type qualifier to separate the two.
@duskwuff: Ah ok, I wasn't aware of that. In that case, just replace const with rom in all of the above, and it should still apply, assuming that the compiler is reasonably behaved. So rom struct block *position = &map[0]; should be the correct definition.
@Adam Rosenfield: Thanks, that solved it!! I was so sure I tried doing that and it had failed :/ guess I should sleep soon haha.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.