This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C182 error kicking my butt

Hopefully this makes sense. I've cut down the actual code to make this short.

I have a series of strings as shown:


char code Num1[] =  {"One  "};
char code Num2[] =  {"Two  "};
char code Num3[] =  {"Three"};


I then have an array of pointers that have all the address of the start of those strings:

code char code *CHNLTable[] = { Num1, Num2, Num3};


I then have a pointer in a function that I want to assign to an element in the array and I get a C182 "Pointer to different objects" warning.

void func(void){	
  unsigned int *myptr;
   myptr = &CHNLTable;

   ...code that uses myptr

}

I don't understand the warning AND the code seems to work fine. Can someone explain to me the dumb thing I'm doing??

  • "I get a C182 "Pointer to different objects" warning ... I don't understand the warning."

    See the description in Chapter 7, Error Messagee in the C51 manual:
    "A pointer was assigned the address of a different type."

      unsigned int *myptr;
      myptr = &CHNLTable;

    You have defined myptr as a pointer to an unsigned int, but CHNLTable is an array of chars!

    "the code seems to work fine"

    That's both the power & the problem with pointers in 'C' - you can do things like this which might happen to work; or they could just go horribly wrong!
    And you are likely to get different results on different compilers!

  • Really? Now I'm more confused because I think CHNLTable isn't full of chars, it's full of pointers which are pointing to arrays of characters. So each entry in CHNLTable is an int, and to increment through it using pointer math the compiler needs to know each offset is two bytes.

    I guess I'm all screwed up now. Can you fix it for me? I'll buy you a beer!


  • Hello:

    code char code *CHNLTable[] = { Num1, Num2, Num3};
    This line tells the compiler that CHNLTable[] contains char pointers. You are assigning each element of the array an address to a character string. The compiler knows how big a pointer is so when you use code like this:
    char *myptr;
    myptr = CHNLTable[2];
    it knows that is must take 2 * "the size of a pointer" and add it to the "address of CHNLTable" to calculate the address of element 2.

    Here is a good on-line tutorial on pointers if you are interested.

    Go to

    http://home.netcom.com/~tjensen/ptr/cpoint.htm

    and click on Read it online

    -Walt

  • Hi Tony,

    Does replacing:
    myptr = &CHNLTable;

    with:
    myptr = (int *) &CHNLTable[0][0];

    work for you?

  • It doesn't change any of the warnings AND it breaks the code. (I just tried it)

  • Right, that's what I thought. Isn't that what I was saying? So it seems to me that you and Andrew are telling me different things? "myptr" points to an array of pointers (actually the first one as show in my original post) which are 16 bit objects; and THEY point to arrays of chars.

    I'm grateful for everyone's replies, now only if I could make some sense out of them! :)

    Now if Jon Ward would chime in!!

  • I think everyone will agree with Walt Conley: CHNLTable[] is an array of pointers.
    '&CHNLTable' is equivalent to 'CHNLTable' as well as '&(CHNLTable[0])'. That is, '&CHNLTable' is a pointer to the first element of the array and it has the type 'char code**'.
    So if you want to convert it to pointer to int (for whatever reason), use 'int* myptr = (int*)&CHNLTable;'. Actually, it's all well described in K&R. Reading this book can only do good.
    Hopefully, I didn't mess up here :-))
    Regards,
    Mike

  • Oops - sorry, you're right!

    char code Num1[] =  {"One  "};
    char code Num2[] =  {"Two  "};
    char code Num3[] =  {"Three"};
    
    code char code *CHNLTable[] = { Num1, Num2, Num3};
    
    void func(void){	
      unsigned int *myptr;
       myptr = &CHNLTable;
    
       ...code that uses myptr
    }

    But you have still defined CHNLTable to be a table of pointers to chars, whereas myptr is a pointer to int - a "different object".

    Just because C51's internal representation of a memory-specific pointer happens to be the same as its internal representation of an int doesn't mean to say that a memory-specific pointer is the same as an int!

    Does that make sense this time?

  • Oh...Just ask...

    Here's what I came up with.

    #include <stdio.h>
    #include <reg51.h>
    
    char code Num1[] =  {"One  "};
    char code Num2[] =  {"Two  "};
    char code Num3[] =  {"Three"};
    
    // Num1, 2, and 3 are arrays (in code) of characters (strings).
    
    code char code *CHNLTable[] = { Num1, Num2, Num3};
    
    // CHNLTable is an array of pointers (in code) to characters (in code)
    // So, each element takes 2 bytes (because the pointer is a code pointer)
    
    void main (void)
    {
    unsigned int *myptr;
    // myptr is a pointer to an unsigned int (a generic, 3-byte pointer)
    
    myptr = &CHNLTable;
    // I'm not sure what myptr should point to...
    // the strings or the pointers to the strings...
    // so, I'm inclined to say this is probably wrong...
    // It yields this warning:
    // *** WARNING C182 IN LINE 21 OF MAIN.C: pointer to different objects
    
    
    // Setup the serial port (stolen from HELLO.C)
    SCON  = 0x50;
    TMOD |= 0x20;
    TH1   = 221;
    TR1   = 1;
    TI    = 1;
    
    
    // Here's one of my interpretations of this...
      {
      char code *jons_ptr;
    
    // jons_ptr is a pointer to a character in code space
    // so, the sizeof jons_ptr is 2
    
      jons_ptr = CHNLTable[0];   // jons_ptr points to the string "One  "
      printf ("jons_ptr = %s\n", jons_ptr); // This prints it
    
      jons_ptr = CHNLTable[1];   // jons_ptr points to the string "Two  "
      printf ("jons_ptr = %s\n", jons_ptr); // This prints it
    
    // If you are trying to get a pointer to an individual string...
    // this is the way to do it...
      }
    
    // Here's another interpretation...
      {
      char code * code *jons_dptr;
    
    // jons_dptr is a ptr to a ptr (in code space) to a char in code space
    // I think this is more like what we really want to get!
    // the sizeof jons_dptr is 2
    
      jons_dptr = CHNLTable;
    // jons_dptr points to the ptr to the string "One  "
    
      printf ("*jons_dptr = %s\n", *jons_dptr);
    // *jons_dptr points to the string "One  "
    
      jons_dptr++;
    // Increment jons_dptr so that it points to the ptr to the string "Two  "
    
      printf ("*jons_dptr = %s\n", *jons_dptr);
      }
    
    while (1);  
    }
    
    // Viola!!!
    

    I tested this with uVision2 V6.21 and got the results that I expected.

    The real problem in the original code (which I think I kept intact) is a clear definition of what you want to point to (the string or the table).

    If you use a table and you want to get a pointer to it, you need to remember that [] => *. In other words a pointer to an array of pointers is really a double pointer (or a pointer to a pointer to a thing).

    Jon

  • That is, '&CHNLTable' is a pointer to the first element of the array and it has the type 'char code**'

    I think this is too imprecise.

    &CHNLTable is the address of CHNLTable.

    Jon

  • I only ment that address of array is a pointer to the first element of the array (in terms of both type and actual binary value). Actually, that is how I would define the term 'address of array'.

  • Yes, however, a pointer has an address whereas an address does not.

    Jon