We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Look at this program:
/*------------------------------------------------------------------------------*/ #include <reg51.h> #include <stdio.h> typedef unsigned long uint32; typedef unsigned short uint16; typedef unsigned char uint8; #define MEMORY xdata #define StructMEMORY xdata typedef struct { uint16 lArg0; uint32 lArg1; } MyStruct; uint8 xdata * MEMORY lPtr; MyStruct StructMEMORY m; void MyInit() { m.lArg0=8; m.lArg1=2; lPtr=(uint8 xdata *)0xddd3; } void bug_0(MyStruct StructMEMORY *p) { static uint32 MEMORY lResults[4]; lResults[0]=((uint32)lPtr) + p->lArg1 + (uint32)(p->lArg0); lResults[1]=p->lArg1 + (uint32)(p->lArg0) + ((uint32)lPtr); lResults[2]=((uint32)lPtr); lResults[2]+=p->lArg1 + (uint32)(p->lArg0); lResults[3]=(uint32)(lPtr+p->lArg1 + (uint32)(p->lArg0)); if (lResults[0]==lResults[1] && lResults[1]==lResults[2] && lResults[2]==lResults[3]) printf("\nNo problems."); else for(;/* BUG */;); } void main() { MyInit(); bug_0(&m); } /*------------------------------------------------------------------------------*/
"You really should change the test in a way that lets you see *which* of the comparisons failed, and the actual values of the relevant variables." Or just try stepping it in the simulator. You could do the same in the Borland debugger.
I simplified the first example into the following example, the difference do exist. But I tend to think it an issue of how to cast a pointer and don't make the complier confused.
typedef struct { uint16 lArg0; } MyStruct; uint8 xdata * MEMORY lPtr; MyStruct StructMEMORY m; void main() { uint32 MEMORY lResults[2]; m.lArg0=8; lPtr=(uint8 xdata *)0xddd3; // something wrong, when casting m.lArg0. lResults[0]=((uint32)lPtr) + ((uint32)(m.lArg0)); result = 1BBA6 // ok; result = DDDB lResults[1]=((uint32)lPtr); lResults[1] += ((uint32)(m.lArg0)); if (lResults[0]==lResults[1]) printf("\nNo problems."); else for(;/* BUG */;); }
27: lResults[0]=((uint32)lPtr) + ((uint32)(m.lArg0)); 28: // ok C:0x041D 90000A MOV DPTR,#m(0x000A) C:0x0420 E0 MOVX A,@DPTR C:0x0421 FE MOV R6,A C:0x0422 A3 INC DPTR C:0x0423 E0 MOVX A,@DPTR C:0x0424 FF MOV R7,A C:0x0425 E4 CLR A C:0x0426 FC MOV R4,A C:0x0427 FD MOV R5,A C:0x0428 900008 MOV DPTR,#lPtr(0x0008) C:0x042B E0 MOVX A,@DPTR C:0x042C FA MOV R2,A C:0x042D A3 INC DPTR C:0x042E E0 MOVX A,@DPTR C:0x042F FB MOV R3,A C:0x0430 CF XCH A,R7 C:0x0431 EB MOV A,R3 C:0x0432 CF XCH A,R7 C:0x0433 CE XCH A,R6 C:0x0434 EA MOV A,R2 C:0x0435 CE XCH A,R6 C:0x0436 E4 CLR A C:0x0437 FC MOV R4,A C:0x0438 FD MOV R5,A C:0x0439 EB MOV A,R3 C:0x043A 2F ADD A,R7 C:0x043B FF MOV R7,A C:0x043C EA MOV A,R2 C:0x043D 3E ADDC A,R6 C:0x043E FE MOV R6,A C:0x043F E9 MOV A,R1 C:0x0440 3D ADDC A,R5 C:0x0441 FD MOV R5,A C:0x0442 E8 MOV A,R0 C:0x0443 3C ADDC A,R4 C:0x0444 FC MOV R4,A C:0x0445 900000 MOV DPTR,#0x0000 C:0x0448 7170 ACALL C?LSTXDATA(C:0370) 29: lResults[1]=((uint32)lPtr);
Hello.
// something wrong, when casting m.lArg0. lResults[0]=((uint32)lPtr) + ((uint32)(m.lArg0)); result = 1BBA6 // ok; result = DDDB lResults[1]=((uint32)lPtr); lResults[1] += ((uint32)(m.lArg0));
lResults[0]=((uint32)lPtr) + p->lArg1 + (uint32)(p->lArg0); lResults[1]=p->lArg1 + (uint32)(p->lArg0) + ((uint32)lPtr);
lResults[2]=((uint32)lPtr); lResults[2]+=p->lArg1 + (uint32)(p->lArg0);
lResults[3]=(uint32)(lPtr+p->lArg1 + (uint32)(p->lArg0));
……. uint8 XDATA * DATA RAMDISK; ……. /* write to file */ void rdisk_fwrite(file_entry XDATA *mfile, uint8 XDATA *buff, uint16 len) { uint16 DATA i; #ifdef __SELECT_ADAPTER_CONFIG uint8 XDATA * DATA ptr; ptr=&RAMDISK[mfile->file_start_ram_index+mfile->file_len]; i=len; while (i--) *ptr++ = *buff++; #else # ifdef __SELECT_TERMINAL_CONFIG MEMORY_UINT DATA ptr; uint8 DATA lByte; /* >>>>>>>>>>>>>>>>>>>>>here the simulator reported strange result in 'ptr' variable */ ptr=((MEMORY_UINT)RAMDISK)+mfile->file_start_ram_index+(MEMORY_UINT)mfile->file_len; /* >>>>>>>>>>>>>>>>>>>>>here the simulator reported strange result in 'ptr' variable */ i=len; while (i--) { lByte=*buff++; RAMDISK_put(ptr, lByte); ptr++; } # endif #endif buff-=len; update_crc(buff, len, &mfile->file_csum); mfile->file_len+=len; }
Sorry, but C51 Version 7.08 compiles the code OK. Maybe you have some special compiler settings or so, but the code prints OK. It seems that the problem has been solved already in Version 7.04 in context with the "integer promotion problems with combined pointer and char arithmetic". Refer also to the Release Notes.