![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
hello188
Joined: 02 Jun 2010 Posts: 74
|
Interesting phenomenon based on compiler versions |
Posted: Sat Oct 20, 2012 2:54 am |
|
|
Hi. I had working code that was compiled using version PCM 4.137
I gave it to my colleague and he complained that it was not working.
I checked his compiler version, and it was 4.132.
So, after about an hour of debugging, I found out the problem.
On compiler version 4.132, the following set of codes seem to translate differently.
Below code works on PCM 4.137, but not on PCM 4.132. Simply put, arr[i] is not equal to TX1_buffer[i] when called except when i = 0.
Code: | //Not working code
void send_bytes1(uint8_t arr[], uint8_t length){
uint8_t i;
uint8_t buffer8;
for(i=0; i<length; i++){
buffer8 = arr[i];
bputc1(buffer8);
}
}
send_bytes1(TX1_buffer, _BUFFER_LENGTH);
|
However, below code works fine on both compiler versions
Code: | //Working code
void send_bytes1(uint8_t * arr, uint8_t length){
uint8_t i;
uint8_t buffer8;
for(i=0; i<length; i++){
buffer8 = *(arr + i);
bputc1(buffer8);
}
}
send_bytes1(&TX1_buffer[0], _BUFFER_LENGTH);
|
What's the difference between the two approach? other than the fact that they look different? Internally, when the are being translated, what happens differently that makes one code work and the other don't?
I thought it was interesting and worth letting you guys know.
Any ideas??
Thanks |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sat Oct 20, 2012 4:01 am |
|
|
It suggests that the subroutine, does not think uint8_t is the same size as the main code does. This is defined in stdint.h. Is it possible that some file is getting included that changes the definitions of this?.
You don't say what chip?. On PCD, an 'int' is an int16, so an old include that has a line like:
typedef unsigned int uint8_t;
on this compiler would cause this type of problem. However you say PCM, which should not do this.
If you want to experiment, try using the 'internal' types, rather than the typedef ones, so 'int8', and see if the problem disappears. It may well be a problem with .132, which is a version I didn't download. Unfortunately CCS's 'fix list' is always so incomplete that it is basically useless, so something like this might have been fixed a version or two late. I tried on an older version, and both approaches seem the same, and on 4.134, where it also seems OK. Also make sure that the project is using the same stdint.h, though this seems to have been unchanged since 2008, and is the same in 3.137 at in much older compilers....
Do a project search and make sure there is not another definition for uint8_t anywhere.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Oct 20, 2012 4:12 am |
|
|
The problem can't be determined unless you show your definition of uint8_t and TX1_buffer. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Oct 20, 2012 1:26 pm |
|
|
All of this really should have been kept in the orginal thread, but anyway...
I made a test program to test the two methods of passing an array,
and definitely vs. 4.132 has a problem. You can see that the array[]
method produces partial garbage as the output.
With vs. 4.137: Quote: | array[] : 123
*array : 123
|
With vs. 4.132 Quote: | array[]: 13@@
*array: 123
|
Test program:
Code: |
#include <18F4520.h>
#fuses HS, NOWDT
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define T1_BUFFER_SIZE 64
int8 t1_buffer[T1_BUFFER_SIZE] = {"123"};
int8 t1_next_in = 0;
int8 t1_next_out = 0;
//----------------------------------
void bputc1(int8 c)
{
putc(c);
}
//----------------------------------
void send_bytes1(int8 array[], int8 length)
{
int8 i;
for(i=0; i<length; i++)
bputc1(array[i]);
}
//----------------------------------
void send_bytes2(int8 *array, int8 length)
{
int8 i;
for(i=0; i<length; i++)
bputc1(array[i]);
}
//======================================
void main()
{
printf("array[ ]: ");
send_bytes1(t1_buffer, sizeof(t1_buffer));
printf("\r");
printf("*array: ");
send_bytes2(t1_buffer, sizeof(t1_buffer));
printf("\r\r");
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sun Oct 21, 2012 2:13 am |
|
|
If you study the result, it looks like .132, is treating the array elements as being int16 in size. So the first entry returns '1', then it jumps forward _two_ bytes, and returns the '3' that is the third character, then goes two characters further, and gets to garbage....
Glad I avoided 132!....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
neil
Joined: 08 Sep 2003 Posts: 128
|
byte boundaries within words screwed up! |
Posted: Wed Oct 24, 2012 6:32 am |
|
|
This is very interesting! I have not written any code for about 3 years and had to revisit an old project.
I found that I was getting garbage results for many of my functions which had previously worked. This was causing all sorts of headaches trying to track down the reason.
I found the reason to be similar to the problem in this post.
For years I have used direct addressing of bytes in an int16 (long) using the old macro: Code: | #define hi(x) *(&x+1) | Suddenly this no longer worked at all. Inspecting the ASM seemed to indicate that indirect addressing was being used (despite only being for 2 bytes - inefficient?) and the offset was being incremented as if an int8 was an int16, so pointing to the next variable in ram, rather than the high byte of the same variable.
I removed this code and instead implemented a union: Code: | union byteexchange{
long word;
int bytes[2];
}; |
This then produced the kind of ASM I was expecting for the other method - directly accessing the bytes within the word.
I am using V4.093 and this problem exists both in PCM and PCH!
Has anyone experienced this with this compiler version?
Regards,
Neil. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
Re: byte boundaries within words screwed up! |
Posted: Wed Oct 24, 2012 7:12 am |
|
|
neil wrote: | This is very interesting! I have not written any code for about 3 years and had to revisit an old project.
I found that I was getting garbage results for many of my functions which had previously worked. This was causing all sorts of headaches trying to track down the reason.
I found the reason to be similar to the problem in this post.
For years I have used direct addressing of bytes in an int16 (long) using the old macro: Code: | #define hi(x) *(&x+1) | Suddenly this no longer worked at all. Inspecting the ASM seemed to indicate that indirect addressing was being used (despite only being for 2 bytes - inefficient?) and the offset was being incremented as if an int8 was an int16, so pointing to the next variable in ram, rather than the high byte of the same variable.
I removed this code and instead implemented a union: Code: | union byteexchange{
long word;
int bytes[2];
}; |
This then produced the kind of ASM I was expecting for the other method - directly accessing the bytes within the word.
I am using V4.093 and this problem exists both in PCM and PCH!
Has anyone experienced this with this compiler version?
Regards,
Neil. |
Your problem is different, and well documented. It is in the 'readme' that comes with the compiler...
The V4 compilers switched to being fully 'C' compliant in the way they handle pointers. So a pointer to a int16, if incremented, increments by the size of an int16. This is _standard_ in C. The older compilers were getting this wrong.
Code: |
#define hi(x) *(((int8 *)&x)+1)
|
You have to tell the compiler you want to treat the pointer as being to individual bytes, so it then works.
Quote from the readme.txt:
"Users that have old code with expressions of the form:
*(&data + i)
need to change them to:
*((int8 *)(&data) + i)
A compiler change was made to be ANSI compliant. "
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
neil
Joined: 08 Sep 2003 Posts: 128
|
|
Posted: Wed Oct 24, 2012 7:17 am |
|
|
Oops! should have RTFM'd Thanks for clearing that up though!
Neil. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|