Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Problems with array of addresses and pointers

Help
GrahamNZ
2008-08-26
2013-03-12
  • GrahamNZ
    GrahamNZ
    2008-08-26

    Hello,
    I have a SDCC project (targeting 8051) that requires to be able to swap between parameter structures. The perfect chance to use pointers and to select the desired structure from an array of structure addresses.

    To verify the concept I have written a small application to ensure I define everything correctly (by analysing the memory consumption) for the SDCC compiler (2.8.0) but have run into a number of problems with it.

    The following are lines from my source file (please read through the /**/ comments as they explain what the compiler produces for various incantations of the tables_1x3[3] constant)...

    // I have verified that these data tables are in code space and occupy 16 bytes each
    const int table1[] =
        {0, 1, 2, 3, 4, 5, 6, 7} ;

    const int table2[] =
        {0, 1, 2, 3, 4, 5, 6, 7} ;

    const int table3[] =
        {0, 1, 2, 3, 4, 5, 6, 7} ;

    // explicitly defined pointer - located in xdata memory and points to data in code memory
    static code int* xdata xdata_ptr1_2code ;

    //const code int* code tables_1x3[3] = {&table1, &table2, &table3} ;
    /* (1) With the above line the compiler produces
       X:\SDCCTrials\arrays.c:136: error 47: indirections to different types assignment from type 'const-int [8]  code-code* ' to type 'const-int code-const-code* '
       X:\SDCCTrials\arrays.c:136: warning 18: Initializer different levels of indirections from type 'const-int [8]  code-const-code* 'to type 'const-int code-const-code* ' */

    //const code int* code tables_1x3[3] = {(code*)&table1, (code*)&table2, (code*)&table3} ;
    /* (2) With the above line the compiler produces
       X:\SDCCTrials\arrays.c:136: warning 18: Initializer different levels of indirections from type 'const-int [8]  code-const-code* 'to type 'const-int code-const-code* ' */

    //const code* code tables_1x3[3] = {(code*)&table1, (code*)&table2, (code*)&table3} ;
    /* (3) With the above line the compiler produces
       X:\SDCCTrials\arrays.c:146: warning 18: Initializer different levels of indirections from type 'const-int [8]  code-const-code* 'to type 'const-int code-const-code* '
       and this warning was repeated three times */

    const code* tables_1x3[3] = {(code*)&table1, (code*)table2, (code*)table3} ;
    /* (4) With the above line the compiler produces no warnings or errors  - but placed table in internal ram!
       Used 2 bytes per entry = 6 bytes of ram for this structure */

    void main(void)
    {
        xdata_ptr1_2code = (code*)&table1 ;   // line 'a'
        xdata_ptr1_2code = tables_1x3[2] ;    // line 'b'

        while (1)
        {
        }
    }

    OK - I fully admit that I may be confused slightly as to the 'function' of my tables_1x3[3] - should it be thought of as a table of addresses, or ints that are later retypecast to code pointers, or code*?

    With examples (1, 2, and 3) is the compiler trying to tell me that I am converting an 8-bit const int to const int? and if so why does it think there is an 8-bit int involved?

    Example (4) compiles but placed the tables_1x3[3] in internal data memory rather than in code memory (I expected the const directive to place in in code space). This is not sutiable for the final project where the tables_1x3[3] is actually 18 by 8 and require 342 bytes of ram.

    Why, when xdata_ptr1_2code is explicitly defined as a code pointer, does the compiler require a type cast on line 'a'?

    Comments invited.

    Regards,
    Graham

     
    • GrahamNZ
      GrahamNZ
      2008-08-28

      To All,
      I have resolved the issue and learnt more about C in the process, knowledge I am pleased to share.

      As with most problems it was a conglomeration of issues.
      1) The base type of tables_1x3 array neede to come from it's own typedef, thus
      typedef const code int* CC_INT_PTR ;

      2) Then define the code constants
      const code CC_INT_PTR tables_1x3[3] = {&table1[0], &table2[0], &table3[0]} ;

      Note: the [0] is required in SDCC even though table1 and table1[0] have the same physical address.  Without them the compiler generates 'error 47: indirections to different types assignment from type 'const-int [49]  code-code* 'to type 'const-int code-const-code* '' error messages.

      Note: If the 'code' directive is ommitted than the table is built in the default (DATA) memory!

      3) Now point yur pointer at the data in the table
          xdata_ptr1_2code = tables_1x3[2] ;

      Note: Now the final typecast is no longer required so the compiler is happy that the two types are equivalent!

      So, there you have it.

      Enjoy and comments welcome,
      Graham

       
    • Maarten Brock
      Maarten Brock
      2008-09-02

      Graham,

      You still do not fully get it. You need the [0] because table1 and table1[0] do NOT have the same address, instead table1 IS the address of table1[0]. With &table1 you're trying to take the address of the address of table1[0]. That is why the compiler tells you there are different levels of indirection.

      And int[8] does not mean an 8 bit integer (there's no such thing outside of bitfields), it means an "array of 8 integers".

      Maarten

       
      • GrahamNZ
        GrahamNZ
        2008-09-02

        Hi Maarten,
        Appreciate your feedback and clarification as to exactly what is the compiler is doing and trying to communicate through the various messages.

        Regards,
        graham