CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Strange problem compiler versions

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

Strange problem compiler versions
PostPosted: Sat Apr 05, 2014 2:54 am     Reply with quote

Hi all,
I have a code that was built in ccs 4.085 for the PIC16F1824 that was sort of array of reference of variables:

Code:

const signed char default_params[28] = {default_vary1, default_vary2, default_vary3, default_vary4, default_vary5};

signed char *def_params[5] = {&vary1, &vary2, &vary3, &vary4, &vary5};

volatile int8 temp = 0;
int8 i = 0;

for (i = 0; i < 5; i++)
   {
      temp = read_eeprom(i);
      if (temp == 0xFF)
      {
         temp = default_params[i];
      }
      def_params[i] = temp;
   }
if (0x25 === vary1)
{
 // the normal function

}

With the version 4.085 this works perfectly well.. but with the 5.020 it doesn't work... it gives the reference/position of the variable "vary1" and not the value of "vary1". Why?
Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Sat Apr 05, 2014 8:33 am     Reply with quote

Because that is what you are declaring it as.

It looks like the older compiler was faulty here, and your program was taking advantage of the fault.

The declaration:

signed char *def_params[5] = {&vary1, &vary2, &vary3, &vary4, &vary5};

Is saying this is an array of five _pointers_ to values. Not the values....
You store the addresses of the variables.
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

PostPosted: Sat Apr 05, 2014 9:49 am     Reply with quote

Hi Ttelmah,

The reason for this is the following:
First: the declaration of each variable:
Code:

signed char vary1 = 0;
........
signed char vary5 = 0;

also, I need this array of variables because I receive the information of the value of each variable from a PC. So I have an array of values that fills each of the variable that I need. After refresh each variable I make also an array of eeprom saves to save the value of each variable.
Also, if there is no value saved in the eeprom, by the default I have a certain values.
So I need to use the variable value.. always... is there any other way to do this?
Regards
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

PostPosted: Sat Apr 05, 2014 9:57 am     Reply with quote

Also,

I have a very similar code in a PIC32 micro with the XC32 V.120 and now V.30 and it works perfectly well. The code is the same.
So I think that it must be an problem of the compiler and I have to make an workaround.
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Sat Apr 05, 2014 11:21 am     Reply with quote

The problem is that:

def_params[i]

is the address of the variable. You then write a value directly to this, which will then be used as the address. *def_params[i] is the value.

*def_params[i] = temp;

is the way to write to the variable itself.

Seriously, arrays of pointers, is a thing that CCS gets wrong in various ways in different version. I've suggested in the past using arrays of long integers instead, and explicitly casting the pointer to a long integer and back when needed.

So:
Code:

long int def_params[5] = {&vary1, &vary2, &vary3, &vary4, &vary5};

volatile int8 temp = 0;
int8 i = 0;

for (i = 0; i < 5; i++)
   {
      temp = read_eeprom(i);
      if (temp == 0xFF)
      {
         temp = default_params[i];
      }
      *((signed char *)def_params[i]) = temp;
   }
if (0x25 === vary1)
{
 // the normal function

}


Forces correct operation of the pointers.

Now understand that you are not using reference parameters, since you don't pass this to a function. If you passed with the & format to a function, this becomes a reference parameter, and talking directly to the variable would affect the original copy. This would work allow the value to be used as you show.
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

PostPosted: Sun Apr 06, 2014 1:38 pm     Reply with quote

Dear Ttelmah,

I use this structure of arrays to save flash memory...because in fact I have 30 variables stored in this array.
I use the value of each variable by the name of each variable
Code:
 if (0x25 == vary1)
{
}
else if (0x19 == vary2)
{
}
else if (temp_sensor4 == vary3)
{
}

But for update, each variable, or for send the value of each variable to the PC (populate) the buffer I use array of pointers. Also, for example if I have more variables, I can easily increase the max_num_variables and the way of work is practical the same.
But yes, the most important part is to reduce the size of the flash memory
Also for receiving the data of the PC I use, for updating/changing the value of each variable:
Code:
 for ( i = 0; i < max_num_variables; i++)
{
  def_params[j] = rs_rcv_buffer[i+3];
}

and for sending the information of the actual value of each value for the PC I use the following:
Code:
for (i = 0; i < max_num_variables; i++)
{
   rs_send_buffer[rs_send_pointer++] = def_params[i];
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 12:30 am     Reply with quote

You are missing the point.

What you are trying to do, is _incorrect C_.
When you say 'similar' for XC32. I'm sure it is not _the same_.

Now understand that an array of pointers is legal C, but you then have to talk to the elements, by accessing the elements, not the pointer.
The exception is an item passed 'by reference' to a function, where '&' is used in the function declaration, and the compiler then sorts out handing the pointer to the function, and dereferences this, so the function can use it as if it was a local variable. Despite your thread title, this is not what you are doing.
That it worked in the old compiler, simply tells you that the old compiler was getting this wrong....

Now the various CCS compilers do commonly get this wrong, and don't handle arrays of pointers well between different versions. I've shown you how instead to store an array of integers, which you load with pointer values, and use as pointers (with a cast). To make this tidy, declare a macro to do this. This works with really old CCS compilers, and modern ones alike (which avoids problems as you update versions).
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 2:12 am     Reply with quote

Dear Ttelmah,

In the xc32 I do the following:

Code:
 signed char vary1, vary2, vary3, vary4, vary5;

const signed char default_params[] = {default_vary1, default_vary2, default_vary3, default_vary4, default_vary5};
char *def_params[4] = {&vary1, &vary2, &vary3, &vary4, &vary5};


Accessing the variables:
Code:
for (i = 0; i < num_max_var; i++)
{
  *def_params[i] = rs_rcv_buffer[i + 2];
}


sending/update variables:
Code:
rs_send_buffer[rs_send_pointer++] = *def_params[Parameter_to_Change];


The idea is to have an array/structure with the value of each variable.
I can't double check if is totally incorrect C because in the past with the GNU compiler and the Visual Studio Compiler I have made similar things to this.
Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 2:50 am     Reply with quote

Yes. Notice the critical extra '*'.....

Exactly what I pointed out in my second post:
Quote:

*def_params[i] = temp;

is the way to write to the variable itself.


You are writing to the pointer, not the variable.....

Use the syntax you had with xc32.
ralph79



Joined: 29 Aug 2007
Posts: 87

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 3:08 am     Reply with quote

In the ancient ccs version if I put the "*" I have an error on compiling...
that was the reason I remove it.
Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Mon Apr 07, 2014 3:23 am     Reply with quote

Yes.

As I said:

"It looks like the older compiler was faulty here, and your program was taking advantage of the fault."

also:

"Now the various CCS compilers do commonly get this wrong, and don't handle arrays of pointers well between different versions."
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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