View previous topic :: View next topic |
Author |
Message |
xMerlin
Joined: 30 Jan 2018 Posts: 5
|
Return struct from a function. |
Posted: Fri Mar 09, 2018 3:33 am |
|
|
Hi,
Using v5.073 version of the PICC compiler on a PIC16LF1827 here. And am facing a problem when trying to return a structure from a function call. According to this and this, I believe below code should work. However, I'm getting the following error: Error#27 Expression must evaluate to a constant.
Code (the error is on the last line):
Code: |
struct tmr_246_config {
int txcon;
int prx;
};
typedef struct tmr_246_config tmr_246_config_t;
tmr_246_config_t mif_tmr6_get_conf(void)
{
tmr_246_config_t tmr_config;
tmr_config.txcon = REG_T6CON;
tmr_config.prx = REG_PR6;
return tmr_config;
}
//-----------------------------------
tmr_246_config_t tmr6_config = mif_tmr6_get_conf();
|
Returning a pointer to a struct works fine. So the following compiles OK:
Code: |
struct tmr_246_config {
int txcon;
int prx;
};
typedef struct tmr_246_config tmr_246_config_t;
tmr_246_config_t * mif_tmr6_get_conf(void)
{
tmr_246_config_t * tmr_config;
tmr_config->txcon = REG_T6CON;
tmr_config->prx = REG_PR6;
return tmr_config;
}
//-----------------------------------
tmr_246_config_t *tmr6_config = mif_tmr6_get_conf();
|
Any ideas where my understanding is wrong? Why doesn't the first piece of code work? Am I completely misunderstanding the topic of returning structs and using typedefs?
Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Mar 09, 2018 3:57 am |
|
|
Two separate issues:
Second first. In the pointer version, you never actually declare any memory to hold the variable. So your pointer is probably pointing off into the RAM somewhere and other things will get overwritten. You need to actually declare a variable and point the pointer to this, or use malloc to allocate some RAM and point to this.
Now the first. This is perfectly OK, except for one thing:
Code: |
tmr_246_config_t tmr6_config;
tmr6_config = mif_tmr6_get_conf();
|
When you declare a variable and initialise it at declaration, the initialisation is done at compile time, and must be to a constant. Hence the error.
You have to declare the variable, then call the function. |
|
|
xMerlin
Joined: 30 Jan 2018 Posts: 5
|
|
Posted: Fri Mar 09, 2018 4:43 am |
|
|
Thanks. First case is clear now. And rather obvious, I'm ashamed to admit.
As for the second, would this then work properly?
Code: |
struct tmr_246_config {
int txcon;
int prx;
};
typedef struct tmr_246_config tmr_246_config_t;
tmr_246_config_t * mif_tmr6_get_conf(void)
{
tmr_246_config_t tmr_config;
tmr_config.txcon = REG_T6CON;
tmr_config.prx = REG_PR6;
return &tmr_config;
}
//-----------------------------------
tmr_246_config_t tmr6_config;
tmr_246_config_t *p_tmr6_config = &tmr6_config;
p_tmr6_config = mif_tmr6_get_conf();
|
It wouldn't, right? Because the memory assigned to the function's internal variable/structure would get freed after the function returns so contents would be unknown. Is my thinking correct?
As for the malloc, I get a Error#12 Undefined identifier -- MALLOC error when trying to use it. Is it even supported in PCW? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Mar 09, 2018 7:02 am |
|
|
Yes, malloc is supported. You have to include stdlibm.h
If you declare the variable as 'static' then the second would work properly. Otherwise as you say the RAM could be being re-used, but (of course), if you simply copy the value out of it as soon as you return, then it could potentially be used. |
|
|
xMerlin
Joined: 30 Jan 2018 Posts: 5
|
|
Posted: Fri Mar 09, 2018 7:08 am |
|
|
Aha. And the required inclusion of stdlibm.h is stated so clearly in the help file. Thank you.
Is there any obvious advantage of using pointers in this case vs just passing the entire structure and using struct? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Mar 09, 2018 9:26 am |
|
|
If the structure was a lot larger, the pointer would be much smaller to move. Otherwise, not really. |
|
|
|