Hello!
I have uVision that compiles fine with the C51 v7.03 compiler and the related package, but not complete with the 8.06. I used two different Keil installations. All files are in the same folder.
In the 8.06 I get linker errors like "object does not fit in to pdata page" and "0080H". This looks like the compiler was thinking the PDATA was only 128 bytes, but it is set to 256 bytes in the startup.a51. Any clue what's different in the newer Keil package?
Also there is a warning in 8.06 (which does not show in 7.03) "converting non-pointer to pointer" on this
ptr_xdata = sPtr_obj->Adresse;
while the vars are set like this:
uchar uc_set_obj( uchar pdata *ptr_Set) { uchar i; uchar xdata *ptr_xdata; struct stOBJADR code *sPtr_obj; sPtr_obj=&Obj[*ptr_Set]; . . . ptr_xdata = sPtr_obj->Adresse; }
The struct stOBJADR has a member "uint Adresse;"
I can see no wrong use of the pointers. I just want to be sure that the warning does not affect the code to not work correctly.
And for the x:th time: you can not absolutely know about pointers and how it is used if you think that the address of a pointer is less important (or more or less irrelevant) than the address of the variable it points to.
Basically, you are ignoring arithmetic on pointers, which is something that is very commonly done.
When you do choose to see a pointer's address, a pointer's value and the value it points to as three separate things, your life will be a lot easier.
char buf[100]; char *p = buf+1; char **pp = &p; *buf = 'H'; *p++ = 'e'; p[0] = 'l'; p[1] = 'l'; buf[4] = 'o'; *(buf+5) = '\0'; *pp = strchr(buf,'\0'); printf("Number of characters in string is %ld\n",(long)(p-buf));
So when reading this value I actually do the same as setting the pointer value directly to the address of the variable And for that, you should tell your friendly compiler that the number you have really is an address - the address of an object of the same type that your left-hand-object (the pointer) is expected to point at.
You are assuming that a pointer is a number and because of this, the compiler should always accept the assign of any number to any pointer without getting upset.
Note that pound and dollar are two currencies. The amount of money are always numeric. But you can't simply assign a dollar value to a pound purchase. If you try to do that, the shop will issue a format conversion warning. The conversion from one currency to a different currency requres a type cast. For currencies, this is normally done by checking the current sell price for dollar and the current buy price for pound. In the case of converting from one currency to another, there is a change to the numeric value. The same thing happens when performing an assign from an integer to a floating point number, or the reverse.
In some special cases, there is no actual conversion performed. But the cast should be there anyway. Not because a change is needed to the numeric value, but because a change is needed to the data type, i.e. to tell the compiler that the object on the left and the object on the right are both of the same data type (or at least of compatible data types) - even if a quick look says something else.
Adding a type cast when assigning a number to a pointer tells the compiler that the numeric source value is a proper value for storage in the pointer. In this case, that the number really is a pointer value and suitable for the pointer you want to assign to.
This is no different from the following:
int a = 5; unsigned b = 5; if (a == b) ...
A lot of compilers will notice that a is a signed integer, and b is an unsigned integer, and will issue a warning about a comparison between signed and unsigned data. The warning is there because there is a reasonable chance that the signed/unsigned mismatch is caused by an invalid assumption somewhere.
When you add a typecast, the compiler will check if it is technically possible to treat the right-hand value as compatible with the left-hand value. If you don't write an explicit typecast, the compiler will check it's available automagic data type rewrite rules (as specified by the standard) to see if it somehow (with or without data loss) can convert the right-hand value into something suitable for the left-hand value. However, unless the compiler is really, really happy about any conversion rules it knows about it will complain by issuing a warning. Some compilers have a larger set of warnings than others. But when they do warn, you should care, because that means you are living on the edge.
In your case, a proper cast will tell your compiler that you have turned off the power and removed the fuse before doing electrical work in your house. The cast will mute the warning since you are giving the compiler a written contract where you, the developer, dearly promises that the value in your uint really, really do represent a good pointer to a variable of the correct data type.
int a = 5; unsigned b = 5; a = b;
Could generate a warning, because some legal unsigned values won't fit in a signed int
Similarly,
int a = 5; unsigned b = 5; b = a;
Could generate a warning, because some legal signed values won't fit into an unsigned int.
In both cases, you can tell the compiler that it's not an accidental oversight by giving an explicit cast.
Exactly the same applies when assigning a non-pointer to a pointer, as has already been explained.