Menu

#3699 reading from 2D array

open
nobody
None
MCS51
5
2024-01-24
2024-01-21
No

I have tried to create an array of strings and to read chars from these strings. Unfortunately, it seems the accessing to the array does not work as expected. The read char is always wrong. Debugging the ASM code showed reading data by using the MOVX instruction although there is no xram.
Using __idata modifier did not help.

#include <at89x051.h>

static const char *const moe = "-- --- .";
static const char *const moi = "-- --- ..";
static const char *const mos = "-- --- ...";
static const char *const moh = "-- --- ....";
static const char *const mo5 = "-- --- .....";
static const char *const g_calls[5] = {moe, moi, mos, moh, mo5};

void main(void)
{
    if (g_calls[0][0] == '-')
        P3_0 = 1;
    else
        P3_0 = 0;
}
>sdcc main.c -o main.ihx -mmcs51 --model-small --debug --xram-size 0 --iram-size 128 --code-size 2048 --out-fmt-ihx
ain.c:12: warning 151: using generic pointer _moe to initialize g_calls
main.c:12: warning 151: using generic pointer _moi to initialize g_calls
main.c:12: warning 151: using generic pointer _mos to initialize g_calls
main.c:12: warning 151: using generic pointer _moh to initialize g_calls
main.c:12: warning 151: using generic pointer _mo5 to initialize g_calls

>sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 TD- 4.3.0 #14184 (MINGW64)

I also tried to use the __code modifier that helped to remove the compiler warnings, but the code still does not work as expected. The read char is a low address of the char, not the char itself.

static  __code const char *const moe = "-- --- .";
static  __code const char *const moi = "-- --- ..";
static  __code const char *const mos = "-- --- ...";
static  __code const char *const moh = "-- --- ....";
static  __code const char *const mo5 = "-- --- .....";
static  __code const char *const mo = "-- ---";
static  __code const char * __code const g_calls[5] = {moe, moi, mos, moh, mo5};

Discussion

  • Petr Pazourek

    Petr Pazourek - 2024-01-21

    The way to get it working is as follows. However from my point of view it is a bug, because there are 3 dereferences of the pointer there.

    #include <at89x051.h>
    
    static __code const char *const moe = "-- --- .";
    static __code const char *const moi = "-- --- ..";
    static __code const char *const mos = "-- --- ...";
    static __code const char *const moh = "-- --- ....";
    static __code const char *const mo5 = "-- --- .....";
    static __code const char *__code const g_calls[5] = {moe, moi, mos, moh, mo5};
    
    void main(void)
    {
        const char *pcall =  (const char *)g_calls[0];
        if (*((__code const char *)pcall[0]) == '-')
            P3_0 = 1;
        else
            P3_0 = 0;
    }
    

    This workaround also does not work in all situation, because the 3rd dereferencing uses only the low address. In a case the high address is not 0, it end up with a wrong result.

    Another workaround is to use a switch() statement for selecting the individual string.

     

    Last edit: Petr Pazourek 2024-01-24
  • Maarten Brock

    Maarten Brock - 2024-01-24

    static const char *const moe = "-- --- .";

    Using the second const will place the variable moe in code memory and so will the literal strings be placed there. But the first const does not change the pointer type from a generic (3-byte) pointer to a (2-byte) code pointer. So moe is a generic pointer here. Adding __code does turn it into a code pointer as you found out.

    static const char *const g_calls[5] = {moe, moi, mos, moh, mo5};

    This defines an array of generic pointers and should not complain when initialized with generic pointers.

    And finally, pcall[0] should be a char and not a pointer.

     

Log in to post a comment.