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

What is the difference for xdata types

Hi c51'wizards

What is the difference in having a variable as:

xdata unsigned char var;

versus:

unsigned char xdata var; ??????

Does it make sense to have a variable as:

xdata unsigned char xdata var; ?????

Please be easy in your answers, since I am a novice in this matter.

Thanks in advanced,

DB

  • What is the difference in having a variable as:

    xdata unsigned char var;

    versus:

    unsigned char xdata var; ??????

    None, but the latter definition is preferred.

    Does it make sense to have a variable as:

    xdata unsigned char xdata var; ?????

    No.

    Jon

  • There is no difference in your examples.

    However,

    as soon as you use pointers, things get a lot more interesting. Pointers can have _two_ memory specifiers in their declaration, one stating what memory type the pointer points to, and the other one stating in which memory type the pointer itself is located.

    For example

    unsigned char xdata * code exampleptr;

    declared a memory-specific pointer in code memory that points to an address in xdata.

  • When first using Keil C I spent some time bungling myself through the specifications of pointers and what they pointed to. So, here is what I currently use, if somebody get use of it, great

                                               // pointer in data in
    #define U8DI  unsigned char   idata * data  // data       idata
    #define U8DX  unsigned char   xdata * data  // data       xdata
    #define U8IX  unsigned char   xdata * idata // idata      xdata
    #define U8XX  unsigned char   xdata * xdata // xdata      xdata
    #define U8IC  unsigned char   code  * idata // idata      code
    #define U8DC  unsigned char   code  * data  // data       code
    #define U8XC  unsigned char   code  * xdata // xdata      code
    #define U8CC  unsigned char   code  * code  // code       code
    
    #define U16DX unsigned short  xdata * data  // data       xdata
    #define U16IX unsigned short  xdata * idata // idata      xdata
    #define U16CC unsigned short  code  * code  // code       code
    #define U16DC unsigned short  xdata * data  // data       xdata
    
    #define U32DX unsigned long   xdata * data  // data       xdata
    #define U32DC unsigned long   xdata * data  // data       xdata
    

    Erik

  • "can have _two_ memory specifiers in their declaration"

    It would be helpful if the Keil documentation contained a clear, explicit definition of precisely which specifier is which; eg,

    <type> <target-mspace> * <pointer-mspace> <identifier>
    


    but it doesn't. :-(

    You are just left to figure it out from an example.

    www.keil.com/.../c51_le_memspecificptrs.htm

  • This is standard C syntax. Consider the use of the const qualifier.

    One way to look at it is that const is left-associative. That is, it applies to the thing to its left. The exception is of course when const is the first thing in the declaration; there's nothing to the left, and it's forced to apply to the thing to its right.

    // equivalent declarations
    const U8 foo; // const U8
    U8 const foo; // const U8

    // with pointers
    const U8* foo; // pointer to const U8
    U8 const* foo; // pointer to const U8
    U8* const foo; /// const pointer to variable U8

    (I happen to prefer the C++ style of putting the pointer with the type, rather than the name. The K&R style "U8 *foo, *bar" is usually justified as "making the * part of the variable name", so that *foo is an integer. Also, because of just this case of multiple declarations on one line. But then, confusing and error-prone syntax means that that's poor style to start with. Put the * with the type and not with the variable, and it helps make the syntax of complex pointer declarations more clear. "foo" is a "pointer to U8", rather than "*foo" is a "U8" -- oh, wait, *foo is a funny name.)

    The other way to look at it is to imagine a vertical line drawn through the "*" in the pointer declaration. Any qualifier to the left of this line applies to the thing pointed to. Any qualifer to the right of this line applies to the pointer itself.

    Keil's mspace qualifers should follow the same syntactic rules. I seem to recall I ran across a case where you couldn't use an mspace qualifer where I thought I might. But I haven't run across a case where the qualifers give different results than const.

  • True, but I still think it'd be helpful if Keil stated it explicitly