array of functions

Programming, for all ages and all languages.
Post Reply
sandras
Member
Member
Posts: 146
Joined: Thu Nov 03, 2011 9:30 am

array of functions

Post by sandras »

I need to have an array which mostly contains function pointers, but also has some pointers to other arrays of functions in it. for example:

Code: Select all

typedef void (*func)(void);
func array1[] = {func1, func2, (func)array2};
func array2[] = {func3, func4};
I'm compiling it with lots of warning flags, and the compiler complains, saying:
program.c:2:31: warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]
How can I make the warning disappear? I would like to keep using the warning flags.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: array of functions

Post by Combuster »

Apart from the forward declaration, you're trying to define an array as { func1, func2, {func3, func4} }, rather than { func1, func2, func3, func4 }.

The result is that you end up casting an array (data pointer) to a function (code pointer), which is forbidden by the C standard (probably because of harvard architectures). Besides, it points out a design flaw in your system since it's not being properly typed - where do you keep the information if an entry is an array or a function? shouldn't they be together in the same object?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: array of functions

Post by h0bby1 »

sometime, doing like that can avoid a warning

func array1[] = {func1, func2, *((func *)((void *)(&array2))};

because pointers of differents types can be casted to any other pointer type according to C

but maybe there is a bug in your code if you attempt to add array2 to array1 it's not the good code :) maybe you should use initializing function to add function in it from an array instead of pre initialized array
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: array of functions

Post by bwat »

Combuster wrote:Besides, it points out a design flaw in your system since it's not being properly typed - where do you keep the information if an entry is an array or a function? shouldn't they be together in the same object?
If it is a statically linked function, wont the type can be determinable at run-time by the fact that all such code routines are stored in the text segment? If the address < _etext then it's a function. This is no different to code that determines the shape of a union at run-time, in fact it is more economical with memory as it is uses implicit information. Plenty of programming languages that lack tagged data will type check dynamically on addresses like this as well. It's very common.
Every universe of discourse has its logical structure --- S. K. Langer.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: array of functions

Post by qw »

User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: array of functions

Post by AJ »

Hi,

Could you explain what you are trying to do at a slightly higher level? Chances are that there is a better implementation. As inferred by Combuster, casting an array to a function pointer just to get it to fit inside another array of a different type probably suggests a broken design.

Cheers,
Adam
sandras
Member
Member
Posts: 146
Joined: Thu Nov 03, 2011 9:30 am

Re: array of functions

Post by sandras »

Basically I'm using threaded code to implement Forth.

I have two stacks and a bunch of functions that operate on them. Function pointers are placed in the arrays. The main loop calls these functions in order, one after the other. Some functions need arguments that cannot be found on the stacks. For example a "call" function would need the address of another array of function pointers. The argument for "call" is placed in the array right after the address to it. This is where the "func array1[] = {func1, func2, (func)array2};" stuff comes from.

Hope this helps.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: array of functions

Post by AJ »

Hi,

I have no knowlege of Forth, but how recursive is this? Could you have a top-level array, which points to "function arrays"? Some of your "function arrays" would contain only one item, but it wouldn't break the typing system (unless you need further nesting on top of this...). If it's any more complex than that, perhaps a different high-level container would work better?

Cheers,
Adam
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: array of functions

Post by Combuster »

Based on what Wikipedia has to say on Forth, there are two primitive instructions in the language:
push immediate (store it as a tag, and the immediate)
call word (store as a tag, and a reference to the word's name)
Because you're not compiling, you can't create functions to load predefined variables, nor can you create functions for newly defined words - or altered ones. And because aritrary numbers can be anything, distinguishing them by address doesn't work either.

Hence if you insist on using threaded mechanics, the logical solution would be to define functions as tuples of the interpreter code responsible for the operation, and any arguments to make it happen - because one value is not going to cut it.

i.e. stored functions are best defined as arrays of structs { void (*operation)(void*); void* data; }, with func being the push operation, a direct call to predefined words, or an indirect call storing, another function (i.e. array of tuples). Next to that, you get the regular call stack and data stack used in actual execution, which shouldn't be too much of a problem.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: array of functions

Post by bwat »

Combuster wrote:Based on what Wikipedia has to say on Forth, there are two primitive instructions in the language:
push immediate (store it as a tag, and the immediate)
call word (store as a tag, and a reference to the word's name)
No. There's more than a few words needed to bring a Forth up. Different authors have a different set of primitives. As one example the UK FIG suggest NEXT, ENTER, EXIT, DOVAR, DOCON, LIT,& @, !, +, BRANCH, ?BRANCH, SWAP, >R, R>.
Combuster wrote: Because you're not compiling, you can't create functions to load predefined variables, nor can you create functions for newly defined words - or altered ones. And because aritrary numbers can be anything, distinguishing them by address doesn't work either.
The instruction LIT takes care of literal data. He doesn't need to parse literal data at run time, LIT knows that literal data will follow it. Now, if he inlines subroutines then he could very well be compiling and he could very well generate machine code to load predefined variables. It's just that he passes all arguments via explicit Forth stack pushes. See Andy Valencia's VAX Forth for an example of that.
Combuster wrote: Hence if you insist on using threaded mechanics, the logical solution would be to define functions as tuples of the interpreter code responsible for the operation, and any arguments to make it happen - because one value is not going to cut it.
You've just halved his code density and removed any opportunity to use any of the common Forth execution models out there.
Every universe of discourse has its logical structure --- S. K. Langer.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: array of functions

Post by Owen »

Code: Select all

union word {
    void (*function)(union word *stack);
    void *ptr;
    uintptr_t uint;
    intptr_t int
}

word code[] = {
    { .function=lit },
    { .uint=1 },
    { .function=lit },
    { .uint=1 },
    { .function=add },
}
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: array of functions

Post by Combuster »

bwat wrote:You've just halved his code density
Which is not true because you obviously did not read.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: array of functions

Post by bwat »

You need to explain that one.
Every universe of discourse has its logical structure --- S. K. Langer.
Post Reply