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 CCS Technical Support

Invalid array reference address in function

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



Joined: 16 May 2024
Posts: 3

View user's profile Send private message

Invalid array reference address in function
PostPosted: Thu May 16, 2024 11:17 pm     Reply with quote

The array "g_cmd_List" is defined within the function "Test" by passing a pointer.
I want the reference address of "a_cmd_List" in the function to be the address where "g_cmd_List" is defined.
However, in the case of an NG farm, address 0x0000 is referenced.

It is OK to declare the structure "g_pos_Part_Expansion" by passing a pointer.I would like to know why the problem occurs with this PIC even though other PICs have no problem even with NG farm.

Uses PIC24FJ512GL406.
Uses PCD Version 5.116.

NG farm

Code:

#include <24FJ512GL406.h>

typedef struct
{
   unsigned int32 Left;
   unsigned int32 Top;
   unsigned int32 Right;
   unsigned int32 Bottom;
} position_t;
position_t g_pos_Part_Expansion;

void Test(byte a_test, byte *a_cmd_List, position_t a_position);
byte g_cmd_List[2];

void main()
{
    byte l_test = 0;
    memset(g_cmd_List, 0x33, sizeof(g_cmd_List) / sizeof(g_cmd_List[0]));
    Test(l_test, g_cmd_List, g_pos_Part_Expansion);
}

void Test(byte a_test, byte *a_cmd_List, position_t a_position)
{
    ;
}


OK farm
Code:

#include <24FJ512GL406.h>

typedef struct
{
   unsigned int32 Left;
   unsigned int32 Top;
   unsigned int32 Right;
   unsigned int32 Bottom;
} position_t;
position_t g_pos_Part_Expansion;

void Test(byte a_test, byte *a_cmd_List, position_t *a_position);
byte g_cmd_List[2];

void main()
{
    byte l_test = 0;
    memset(g_cmd_List, 0x33, sizeof(g_cmd_List) / sizeof(g_cmd_List[0]));
    Test(l_test, g_cmd_List, &g_pos_Part_Expansion);
}

void Test(byte a_test, byte *a_cmd_List, position_t *a_position)
{
    ;
}


Last edited by kaihatsuk on Fri May 17, 2024 1:59 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri May 17, 2024 1:56 am     Reply with quote

You 'NG form' version, as posted, builds correctly for me with your compiler.
Are you sure you have posted it exactly as it fails?.
kaihatsuk



Joined: 16 May 2024
Posts: 3

View user's profile Send private message

PostPosted: Fri May 17, 2024 2:03 am     Reply with quote

sorry.
The # at the beginning was missing.

Even with the modified code, the value is incorrect.

The address of g_cmd_List is 0x810.
The address referenced by a_cmd_List is 0x0000.

In case of OK farm, the address referenced by a_cmd_List will be 0x810.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri May 17, 2024 4:55 am     Reply with quote

You are misunderstanding what a structure name actually 'is'.

In C, the name of an array is synonymous with it's address. However a
structure name is not synonymous with it's address. You can use the name
to 'fill' an address variable, but when you pass a structure to a function,
you pass a copy of this variable (just as with a normal variable), not it's
address. It'll actually be passed on the stack. In the smaller C's, there
is no stack, so you can reference the copy as it is in memory, but on
the DsPIC's, this is no longer true. If you want the address, you need to
pass this.

So you are doing something that isn't actually legal in C, but just happens
to work on the smaller PIC's where everything passed is in RAM. On
any other processor or 16bit PIC, it just won't work. You are actually
accessing the copy 'in memory' when you do this on the smaller PIC's,
not the original structure. You can prove this by changing a value in the
structure in the function. The original won't change.
kaihatsuk



Joined: 16 May 2024
Posts: 3

View user's profile Send private message

PostPosted: Mon May 20, 2024 5:41 pm     Reply with quote

Thank you for replying to my post

When I contacted CCS officials, they reported that it was a compiler bug.

Looks like I'll have to find another way to work around it until the bug is fixed.

Quote:

I did some testing and determine this is a bug with the PCD compiler related to passing a structure to a function. I forwarded the bug to the compiler developer to fix. You can work around the problem in a couple ways. First move the structure parameter to the first parameter of the function for example change the function and prototype to the following:

void Test(position_t a_position, unsigned int8 a_test, unsigned int8 *a_cmd_List);

void Test(position_t a_position, unsigned int8 a_test, unsigned int8 *a_cmd_List)
{
;
}

Then call the function as follows:

Test(g_pos_Part_Expansion, l_test, g_cmd_List);

Second use a pointer for passing the structure to the function, for example:

void Test(unsigned int8 a_test, unsigned int8 *a_cmd_List, position_t *a_position);

void Test(unsigned int8 a_test, unsigned int8 *a_cmd_List, position_t *a_position)
{
;
}

Then call the function as follows:

Test(l_test, g_cmd_List, &g_pos_Part_Expansion);
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue May 21, 2024 1:55 am     Reply with quote

They are wrong.
It is not a compiler bug. It is correct C.
The structure name _IS NOT_ it's address in C. For an array it is, and is
defined as such in the manual. For a structure it explicitly is not.
As I said the reason it worked before, was an 'oddity' of the smaller PIC16's
and PIC 18's, which do not have a stack. The variable is therefore passed
'in RAM, and you can treat the address of this as a pointer. On the 16bit
PIC's you have a proper stack, and the variable is passed in the stack,
so there is no 'address' to work with.
CCS



Joined: 31 Oct 2005
Posts: 8

View user's profile Send private message Send e-mail

PostPosted: Tue May 21, 2024 3:03 pm     Reply with quote

There is a mixture of problems here. First in C array names are pointers and structure names are not. Structures are passed by value, the whole structure is passed, and array's are passed by reference.

The user in the original post does need to use & or * in the parameter declaration in order to pass a pointer to the structure and if * also use a & in the call argument.

Second there is a compiler optimization bug where when one structure is passed by value sometimes another pass by reference argument is not passed correctly. This only happens in PCD. It has been fixed for the next release. Contact support if you want a pre-release copy.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed May 22, 2024 12:39 am     Reply with quote

Hurrah. Smile

As I tried to tell the poster, what he was doing was not legitimate C. Sad
It is actually very interesting that it dd work with the PIC16/18 chips.

If he wants to use a pointer, he has to pass an address!....

Thanks for posting this.
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