Hi, Is this a valid construct in you Keil C-251 compiler? unsigned char data buf[20]; typedef struct { int i; int j; } TEST_T; #define GetStruct() (*(TEST_T *)&buf[2]) void Test(void) { GetStruct().i = 3; } Notice that buf is in the data area and I'm type casting it to a TEST_T struct in the default memory area (which is in far). V3.53 of the compiler compiles buggy code when similar scheme is used. If I change the buf memory area to "near", or if I change the macro to #define GetStruct() (*(TEST_T data *)&buf[2]) or #define GetStruct() (*(TEST_T *)(unsigned char *)&buf[2]) then it compiles good code. Question is, was there something fundamentaly wrong with what I did in the macro? Andy
Hi, The only pointer type I used are "data area" pointer and generic pointers. I'm converting the "data area" pointer to generic pointers in the macros (at least that's what I intended). I have created a very simple compilable program to illustrate my problem. The source is included at the end. I ran this program in the built-in simulator and found that if the project's "Memory Model" is set to "Tiny" or "XTiny", then the program would work by assigning the value of 3 to buf[3]. If the "Memory Model" is set to anything else like "Small", then the program would not work as intended. The "Memory Model" affects what a generic pointer is. And "(L_MBUS_READ_T*)" is defining a generic pointer. From my understanding, the statement (*(L_MBUS_READ_T*)&buf[2]) is asking the compiler to convert the pointer to &buf[2] to a generic pointer and then derefernece it. So this should work regardless of what memory area buf is allocated and regardless of what the Memroy Model is set for the project, right? Funny thing is if L_MBUS_READ_T does not contain the union, then it would work.. Andy Here's the program /* ========================== */ unsigned char data buf[20]; typedef struct { union { float IEEE[1]; /* float */ short decimal[1]; /* Virtual decimal. */ } out; } L_MBUS_READ_T; /* Access to the buffers. */ #define L_MBusReadStruct() (*(L_MBUS_READ_T*)&buf[2]) void main(void) { unsigned char i = 0; L_MBusReadStruct().out.decimal[i] = 3; buf[0] = 0; }