this "extract to show" compiles with the warning. I definitely do not want the overhead from mspace ignored. What am I missing in making this mspace dependent i.e VFcPtr always code.
here void VFDcdatLgt(unsigned char code VFcPtr[], VFcCcnt); unsigned char code VFinit[] = {0x1b, 0x40}; unsigned char xdata GCXvfdBuf[40]; void main (void) { VFDcdatLgt(VFinit, 2); // in initialize } /*- end main -*/ here void VFDcdatLgt(unsigned char code VFcPtr[], VFcCcnt) { unsigned char VFDCtemp; for ( VFDCtemp = 0 ; VFcCcnt !=0 ; VFDCtemp++, VFcCcnt--) { GCXvfdBuf[VFDCtemp] = VFcPtr[VFDCtemp]; } }
Note that the example at the end of the online description of this message is incomplete: http://www.keil.com/support/man/docs/c51/c51_c258.htm For the full description, see the PDF manual.
"At the risk of being called a pedant..." You're a pedant! there. ;-) trouble is, we're into the level of detail now where it all gets very pedantic... "I suspect the actual difference is in the syntactical scope of the 'code' keyword." yes - that's the kind of thing I was trying to get at. "For the array-style declaration, this distinction would appear to be impossible (there's no * you can stay to the left or right of)." Yes: because, with an array, there is no pointer to be stored anywhere - you just use the name, and the compiler knows implicitly to insert the address at compile time.
void func(array[]) passes a pointer to the array At the risk of being called a pedant: that's not exactly true. What this passes is a pointer to the first element of the array, not the array itself. The difference is that you can't modify the array itself through that pointer, but only its contents. I suspect the actual difference is in the syntactical scope of the 'code' keyword. In a pointer, there are two things 'code' can modify, depending on where exactly you place the keyword: the memory space of the pointer itself, or of what it points to. For the array-style declaration, this distinction would appear to be impossible (there's no * you can stay to the left or right of).
1)Personally, I say the "func(*array)" is clearer as it describes exactly what is actually passed - a pointer 2)But I guees that you find "func(array[])" clearer...? ;-) 1) show what is passed 2) show what is used a proverb "some like the mother, some like the daughter" describes our "argument" rather well. Erik
"void func(array[]) void func(*array) are equivalent, the only difference being that one is clearer than the other." But, I suspect, the opinion as to which one is the clearer is a subjective one...? ;-) Personally, I say the "func(*array)" is clearer as it describes exactly what is actually passed - a pointer - and gives no room for anyone to think that the whole array might actually be passed. But I guees that you find "func(array[])" clearer...? ;-)
I imagine it has some thing to do with the following: char code *ptr_to_code is a pointer in the default mspace that points to Code space; char code * code code_ptr_to_code is a pointer in Code space that also points to Code space. char code code_array[] is an array in Code space. You can use the name "code_array" as a reference to the location of the array, but it isn't exactly a pointer - it is not a separate variable stored somewhere. No doubt it's somewhere in this extra possibility of specifying both the location of a pointer and it's pointed-to mspace that it all falls down?
anyhow: void func(array[]) passes a pointer to the array, not the array itself to the function. So the Mspace parameter specify the location of the array, not the pointer. so void func(array[]) void func(*array) are equivalent, the only difference being that one is clearer than the other. Thus, both formats should accept mspace modifiers. Erik
A further thought: "You can't specify an mspace for a parameter, but you can for the target of a pointer." Similar to the way that you can't specify diffenent mspaces for the members of a structure, but a structure can contain pointers to different memory spaces!
"it works with pointers, it works with char, int etc; there is no reason it should not work with arrays." I think there probably is - as Drew said, "You can't specify an mspace for a parameter, but you can for the target of a pointer." (my emphasis) I think when you defined your parameter as an array with the 'code' mspace, you were effectively saying, "this parameter is passed in code space" - which obviously can't happen When you use the pointer version, as Drew & I suggested, you are saying this parameter points to an address in code space - which is quite a different thing. Although pointers & array names are very nearly equivalent in 'C', there are still subtle differences - and this is one of those places where it matters! In ANSI-speak, an array name cannot be an lvalue; ie, it cannot appear on the LHS of an assignment. As mentioned earlier, I seem to remember falling over this before - and I think I used an explanation on the lines of the above to convince myself of what was going on!
FYI it works with pointers, it works with char, int etc; there is no reason it should not work with arrays. Keil, please take note. Erik
I'd also suggest void main (void) { VFDcdatLgt(VFinit, sizeof(VFinit)); // in initialize } /*- end main -*/ as stated this is a cut down reduced etc 'demo of problem' it does in no way demonstrate my writing/coding style I'll try the pointer, but still think that what I did should work. Thanks, Erik
How about: void VFDcdatLgt(unsigned char code* VFcPtr, VFcCcnt); instead? You can't specify an mspace for a parameter, but you can for the target of a pointer. I'd also suggest void main (void) { VFDcdatLgt(VFinit, sizeof(VFinit)); // in initialize } /*- end main -*/ Or, more likely, a #define for the size of the array. It's rare (at least for me) to have a use for an array of unknown size since so many routines wind up needing to know the size. Might as well have a constant for it. And supplying a explicit size lets the compiler / lint check the initializer for completeness, which helps when changing the size of the array.
I presume this is a C51 question? I seem to remember seeing something like this sometime in the distant past... What if you try:
void VFDcdatLgt(unsigned char code *VFcPtr, VFcCcnt)
View all questions in Keil forum