|
|
View previous topic :: View next topic |
Author |
Message |
kaihatsuk
Joined: 16 May 2024 Posts: 3
|
Invalid array reference address in function |
Posted: Thu May 16, 2024 11:17 pm |
|
|
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: 19529
|
|
Posted: Fri May 17, 2024 1:56 am |
|
|
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
|
|
Posted: Fri May 17, 2024 2:03 am |
|
|
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: 19529
|
|
Posted: Fri May 17, 2024 4:55 am |
|
|
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
|
|
Posted: Mon May 20, 2024 5:41 pm |
|
|
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: 19529
|
|
Posted: Tue May 21, 2024 1:55 am |
|
|
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
|
|
Posted: Tue May 21, 2024 3:03 pm |
|
|
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: 19529
|
|
Posted: Wed May 22, 2024 12:39 am |
|
|
Hurrah.
As I tried to tell the poster, what he was doing was not legitimate C.
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. |
|
|
|
|
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
|