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

Possible bug with unsized _at_ arrays (C51 v6.14)

While working with some memory-mapped I/O, I came across some behavior which may be construed as a bug.

I declared my memory-mapped stuff as an unsized array of char's in xdata. C51 produced no errors, but the array was positioned at address 0x0000.

The linker then reported a L107 error due to overlap with the normal xdata variables.

I fixed the problem by specifying a size to the array, but this smells like the wrong behavior to me. Am I all wet?

Remove the "//" on line 5 to fix the bug.

/*
   Keil v6.14 memory space bug(?) demonstration
*/

#define NUM // 1

char xdata test1[NUM] _at_ 0x1E00;

char xdata test2[NUM] _at_ 0x1F00;

char xdata test3;

void main(void) {
   char x;

   x = test1[0x13];
   x = test2[0x25];
   x = test3;
}

  • Hmmm...

    But what does an "unsized" array actually mean?
    It's really just a pointer, isn't it?
    So why not just say

    char xdata *p = 0x1E00 // Pointer to XDATA location 0x1E00
    Remember, you can still use the [] "index" operator with a pointer; ie,
    p[0] addresses location X:0x1E00;
    p[1] addresses location X:0x1E01;
    etc

    or you could use the XBYTE, XWORD, etc macros

  • A declaration like

    char xdata test1[];
    is known as an "incomplete type"
    - the compiler doesn't actually allocate any storage unless you initialise it, and then the size is inferred by the initialisation; eg,
    char xdata test1[] = "stuff";

    So, if the compiler doesn't actually allocate any storage, how can it place it at any particular location!?


  • So, if the compiler doesn't actually allocate any storage, how can it place it at any particular location!?


    Thanks for the reply!

    Well, it may sound kind of silly, but I think a zero-byte field at a specific address is legitimate in this case.

    My solution was to give the declaration a size - and this worked just fine.

    However, I still think it's kind of a bug in that the compiler dropped the 0-byte-long array at address 0, not the address I gave it.


  • But what does an "unsized" array actually mean?
    It's really just a pointer, isn't it?
    So why not just say

    char xdata *p = 0x1E00 // Pointer to XDATA location 0x1E00
    

    Wouldn't this allocate a 2-byte pointer containing the value 0x1E00? In the large memory model, "p" would be located in xdata and a reference to p[0] would have to go through two DPTR references.

    I think...

  • Note that you can explicitly specify both the location of the pointer, and the memory space which it addresses; eg,

    char data * xdata str;    /* ptr in xdata to data char */
    int xdata * data numtab;  /* ptr in data  to xdata int */
    long code * idata powtab; /* ptr in idata to code long */
    from the C51 manual, chapter 3.

  • ... or use the XBYTE, etc, absolute memory access macros?