Menu

[z80] Const string pointer bug?

Help
Aoineko
2022-09-17
2023-06-10
  • Aoineko

    Aoineko - 2022-09-17

    Hello,
    With the following code:

    struct InvestPic { const c8* Name; };
    
    const c8* test1 = "My test #1";
    const c8 test2[] = "My test #2";
    const struct InvestPic g_InvestPics[] =
    {
        { test1 },
        { test2 },
    };
    

    I get the address of the test2 string with g_InvestPics[1].Name (declared with type const c8[]) but not for test1 with g_InvestPics[0].Name (declared with type const c8*).

    For the string test1, the compiler allocates 2 bytes in RAM which stores the address of the string. The label test1 points to this space in RAM.
    So the pointer to the string becomes a pointer to a pointer to the string.

    This doesn't seem like normal behavior.
    Can you confirm this?
    If not, I would like to understand ^^

    SDCC version = 4.2.0 #13081
    Compile options = -c -mz80 --vc -DTARGET=TARGET_ROM_32K -DMSX_VERSION=MSX_1 -I. -I.\..\..\engine\src -I.\..\..\engine\content --opt-code-speed D:\Dev\Private\MSX\MSXgl\projects\samples\s_hello.c -o .\out\

     
  • Job Bolle

    Job Bolle - 2022-09-18

    It is normal behavior.

    So the pointer to the string becomes a pointer to a pointer to the string.

    No, it is just a pointer to the string. Unless you argue that every variable is a pointer because it has an address in memory:

    const int some_int = 0x1234;
    

    results in this:

    _some_int:
        .dw #0x1234
    

    "For the int some_int, the compiler allocates 2 bytes in RAM which store the value of the int. The label _some_int points to this space in RAM. So the int becomes a pointer to the int." (See how this doesn't hold..)

    In your example,

    test1 is a pointer to a c8. It is not even const, you can assign values to it, i.e. make it point to a different c8. This is why it is in the 'initialized' area, with __xinit__test1 in the 'initializer' area. The contents of what it points to is const. (like "one" in the example below)

    If the pointer test1 itself were const (like "four" in the example below), it would (could?) be in the 'code' area and look like this:

        .area _CODE
    _test1:
        .dw __str2
    

    test2 is an array of c8. (like "two" in the example below)

    const char *one = "one";    /* one can be modified but *one can not */
    const char two[] = "two";   /* neither two nor *two can be modified */
    char *three = "three";      /* both three and *three can be modfied */
    char *const four = "four";  /* four can not be modified but *four can */
    char five[] = "five";       /* five can not be modified but *five can */
    
    int main(void)
    {
        one = two;              /* this is fine */
        one = three;            /* this is fine */
        two = one;              /* error: can not assign to read-only var */
        three = one;            /* warning: assignment discards qualifier */
        three = two;            /* warning: assignment discards qualifier */
        three = five;           /* this is fine */
        four = one;             /* error: can not assign to read-only var */
        five = two;             /* error: can not assign to read-only var */
        five = three;           /* error: can not assign to read-only var */
    
        one[0] = 'x';           /* error: can not assign to read-only var */
        two[0] = 'x';           /* error: can not assign to read-only var */
        three[0] = 'x';         /* this is fine */
        four[0] = 'x';          /* this is fine */
        five[0] = 'x';          /* this is fine */
    
        return 0;
    }
    
     
    • Aoineko

      Aoineko - 2023-06-10

      Thanks for the detailed explanation.

       

Log in to post a comment.