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

"Recursion not permitted" Error message

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



Joined: 02 Feb 2013
Posts: 7

View user's profile Send private message

"Recursion not permitted" Error message
PostPosted: Sat Feb 02, 2013 12:07 pm     Reply with quote

Hi everybody,

I am was writing a firmware that was not compiling so I made the smallest version of it that still shows the error.

I think that the compiler is not doing the job right...

Thank you for any tips!


Code:
#include <18f4620.h>

typedef void (*task_entry_t)(void); // pointer the thread function

void task_PARENT(void);
task_entry_t PARENT = &task_PARENT;

void task_CHILD(void);
task_entry_t CHILD = &task_CHILD;

void task_CHILD (void) {}

void task_PARENT (void) { CHILD(); }

void main(void) { CHILD(); }
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Feb 02, 2013 12:30 pm     Reply with quote

what are you trying to accomplish ?
barbiani



Joined: 02 Feb 2013
Posts: 7

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 12:33 pm     Reply with quote

Pseudo multitasking... The code was bigger but I removed most of it.

The portion I've posted does not even compile.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Feb 02, 2013 12:44 pm     Reply with quote

Quote:

typedef void (*task_entry_t)(void); // pointer the thread function



makes my head spin - redefining "void" in terms of a dereferenced pointer
TO(?) the value of "void" ??
WTF ???? is that about ??
barbiani



Joined: 02 Feb 2013
Posts: 7

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 12:48 pm     Reply with quote

no... that is a pointer to a void function.
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 2:19 pm     Reply with quote

And you are using correct syntax for it. I use that syntax a lot as well.

I believe the problem is this:

Function pointers are very difficult to handle in the PIC series chip due to hardware limitations, but they are doable. In order to have them work, the CCS compiler calls an internal function (you can see this in the LST file) that takes the address in the function pointer and runs it withing that routine. Trying to run a function pointer within a function pointer requires that you execute that special internal function within another copy of the special internal function, which would be recursion, and the compiler does not do recursion to my knowledge. In short, your function pointers cannot call function pointers if what I understand is correct. You'll probably have to work out a method to keep your function pointers one level deep.
barbiani



Joined: 02 Feb 2013
Posts: 7

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 2:29 pm     Reply with quote

Yes. But can you see that the only thing this program does is to call task_CHILD and this function does nothing? I think there is no recursion.

What do you mean by 'one level deep'?
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 3:21 pm     Reply with quote

barbiani wrote:
Yes. But can you see that the only thing this program does is to call task_CHILD and this function does nothing? I think there is no recursion.

What do you mean by 'one level deep'?


Yes, but with function pointers, unlike normal functions, CCS will look at creating the code for task_PARENT() since it is assigned to a variable, even if that variable is never ever used.

When it creates PARENT, it will create the code for task_PARENT(), which calls CHILD() which is linked to task_CHILD();

So even though you are not calling PARENT yet, the compiler will go ahead and assume you will in order to create the function pointer and assign the task to it.

The process for the PARENT variable IF it were to be called is thus (pseudo code):
Code:

call CCS_Internal_Function_Pointer_Caller(PARENT){
    load task_Parent() address;
    run PARENT(){
        call CCS_Internal_Function_Pointer_Caller(CHILD){
           load task_Child() address;
           run CHILD(){
              //child code here
           }
        }
    }
}



Notice that CCS_Internal_Function_Pointer_Caller() is called within itself (recursion).

Even though you don't call it in the main, by making the function pointer for PARENT and assigning it to task_PARENT(), you are causing the compiler to attempt recursion internally.

EDIT: "one level deep": Notice in my pseudo code how there are 2 "levels" of CCS_Internal_Function_Pointer_Caller()? I refer to that as 2 levels deep. One level deep basically means don't call function pointers within function pointer functions.
barbiani



Joined: 02 Feb 2013
Posts: 7

View user's profile Send private message

PostPosted: Sat Feb 02, 2013 3:39 pm     Reply with quote

Now I understand! Thank you for your time and sharing this Smile .

One function calling another was a feature that would simplify the final application a lot.
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