Hi to all,
I have built this struct:
struct pointers {
uint8_t * p1;
uint8_t * p2;
}
struct pnt;
then I have initialize it:
pnt.p1 = &array[0];
pnt.p2 = &array[15];
If I calculate
uint16_t tmp = (pnt.p2 - pnt.p1);
the result is 2;
but if I calculate
uint8_t * a = pnt.p1;
uint8_t * b = pnt.p2;
uint 16_t tmp = b - a;
the result is 15 as I expected.
So, why in the first case I obtain the difference between the address of the elements of the struct (2) and not the difference of the address pointed by p2 and p1 (15)? why I cannot use pnt.p2/pnt.p1 as two usual pointer variable?
I shortly tried to reproduce it, but it works for me. I get 15 for both cases. Can you provide a compilable project which shows the issue?
Also which version of the tools did you use? Which compiler options? I used MCU10, default options.
Daniel
typedef unsigned char uint8_t;typedef unsigned int uint16_t;struct pointers { uint8_t * p1; uint8_t * p2;};uint8_t array[15];struct pointers pnt;static uint16_t tmp1;static uint16_t tmp2;void main() { pnt.p1 = &array[0]; pnt.p2 = &array[15]; tmp1 = (pnt.p2 - pnt.p1); { uint8_t * a = pnt.p1; uint8_t * b = pnt.p2; tmp2 = b - a; } for (;;) {}}
Surely just a typo, but the array size needs to be 16 bytes or the pointers aren't pointing to the same array. And pointer arithmetic on pointers pointing at unrelated memory is undefined behavior.
Hi Lundin, yes it is a typo (in my case it is bigger). I'm using CodeWarrior Ide 5.9.0 Build 2830. Default options. I have also tried to disable optimizations, but it doesn't change.
I have built a new project (attached file). The result is the same: tmp1 = 2; tmp2 = 15
p.s. if I dissasemble it i find
ANSI-C/cC++ Compiler for HC08 V-5.0.26 Build 8120, Apr 30 2008
and
23: tmp1 = (pnt.p2 - pnt.p1);
000e a602 [2] LDA #2
0010 c70000 [4] STA tmp1
Hello Roberto,
I did attempt to run your test project on CW 6.3, and obtained the results (tmp1 = 15; tmp2 = 15; ), as was expected. Again, the default options were being used.
There were a couple of C2705: "Possible loss of data" warnings that occurred. The warnings could be eliminated by casting the result of each pointer subtraction, which did not affect the results obtained.
tmp1 = (uint16_t)(pnt.p2 - pnt.p1);
.
Since tmp1 is an unsigned variable, there would be a definite problem if (pnt.p1 > pnt.p2) were to ever occur.
Regards,
Mac
The C standard defines that the result of a pointer substraction is of the specific type ptrdiff_t. This is required by be a signed integer, and its size is implementation-defined. On CW for HC08 it will be sint16_t.
The possible loss of data warning appears to be completely bugged and illogical in CW, as discussed recently in this post:
https://community.freescale.com/message/74828#74828
Regarding receiving the wrong value, please note that the compiler is free to do any optimizations as the variables tmp1 and tmp2 aren't used by the program. To guarantee a correct result for this particular code, you must declare them as volatile.
Hi Big Mac! Thank You! I know the issues about warnings, but it is only a test.
@ Lundin I still get 2 and 15 also if I declare tmp1, tmp2 as volatile. In my original code, however, the variable tmp1 it is used by the program. And I get the result 2.
Should I install a new version of cw?
Flashback:
I managed to reproduced the described bug in CWHCS08 6.0.
Loading the very same project, with same compiler options, into CWHCS08 6.3 gives the correct result.
And wow, this is actually a pretty serious compiler bug... I'm going to read the 6.3 release notes in detail now. Anyone know where to find them on Freescale's messy site?
I don't think they are available on the web site, but since you have the installation, they are available in the CW folder (e.g. C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.3\Release_Notes\HC08\Notes_HC08_Compiler.txt).
Yeah that file I found, but it only goes up to V5.0.32. I guess they stopped writing documentation from there...
You cango to this CodeWarrior V6.3 update page and click on the "i" button for each download file to get information about the update. I don't think it has the detail you're looking for, but might be worth a look.
---Tom
I actually made a support request for this mythical list of changes after I posted here. Freescale support has since then been giving me various irrelevant documentation over CWHC08 5.0 and CW for Coldfire. Whether it is the support lacking knowledge about CW, or whether it simply is the CW team that doesn't document any changes made to the product, I don't know. It seems impossible to find any documentation anyhow.
Updating at 6.3 I have no problem. Now i have update also 6.2 and I try.
Here
http://www.freescale.com/files/soft_dev_tools/doc/support_info/RN_CWMCUS_6_2_2.txt
there is the documentation.
I think it is
MTWX29785: RS08 compiler: the generated code for pointer subtraction may be incorrect when the pointer is a member of a structure.
But, why rs08 compiler? I think I'm using HC08 ...
Updating will probably solve the problem. It must be a bug fix since the release of your compiler version. For some reason I see nothing really related in the release notes (maybe I didn't look careful enough). Maybe you should open a service request anyway. The release notes should have mentioned the fix.