I need your help in writing a efficient program.
I have approx 50 functions say call_1(), call_2() ... call_50(). I need to call them based on the index read from a data packet, i.e if the field in data is 25 in need to call call_25(), if 10 then call_10().
I have written this in if else condition like
if (index == 5)
call_5()
elseif (index == 6)
..so on ..
But I think this is not the efficient way of writing. Any other ideas of implementing this scenario?
Can function pointers help here?
Appreciate your help. thanks.
Yes, use a lookup table of function pointers:
typedef void(*fp)(void);
void call_01(void);
void call_02(void);
/* ... */
fp functions[] = { &call_01,
&call_02,
/* ... */
};
void call()
{
unsigned int n = get_index();
functions[n]();
}
If the arguments are same for all 50 functions, use an array of function pointers:
typedef void (*FieldHandler)(void);
const FieldHandler handlers[50] = { call_0, call_1, /* ... and so on ... */ };
Then you just index into the array and call:
handlers[index]();
You can use an array of function pointers there easily, if all your functions have the same signature.
typedef void (*func)(void);
...
func dispatch_table[] = {
func0,
func1,
func2,
...
func50,
};
And later use like this
int function_index = packet_get_func_index( packet );
...
dispatch_table[ function_index ]();
Yes, function pointers are the way to go here.
I would suggest creating a table of function pointers and since your input is an index, you just index into the table to call the right function.
I'd use a switch statement:
switch(index) {
case 1: return call01();
case 2: return call02();
case 3: return call03();
}
This is not a lot more code than using function pointers, and it's (imho) more concise.
Yeah, that is pretty inefficient. I think the best way to proceed is to write a dispatcher of this form in the range of 0 - 255:
void (*dispatcher[255]);
Of course, you would need to assign all the necessary functions instead of doing the if statements, but this would be a heck of a lot faster:
dispatcher['a'] = &call_1;
dispatcher['b'] = &call_2;
dispatcher['c'] = &call_3;
...
Then you can just do:
dispatcher(index) and it would know which function to execute.
Hope that helps.
Related
I have a piece of code that will be executed many times (5,000+), and an if statement that will be true only the first time. I've thought of using a "FIRST" variable and compare it each time, but it just seems like a waste to check it every single time, even if I know it's not needed.
bool FIRST = true;
void foo(){
if(FIRST){
/* do something only once */
FIRST = false;
}
/* something something... */
}
I also don't know if there is some compiler optimization that does this automatically, or another way to do it; if there is, please let me know.
And yes, I know that a mere if statement isn't a big thing, but it just annoys me.
If you're using gcc, there are macros called unlikely and likely that can allow it to make optimizations based on a condition.
In your case the condition will only be true the first time, so you would use unlikely:
if (unlikely(FIRST)) {
From a compiler optimization point of view, I think an if statement is your best bet, as it will probably compile down to something like a single JNZ, so as long as FIRST stays true, it will be pretty optimized.
You might also want to take a look at this thread
You can call the function via a function pointer and remove the if check on the second call by changing the function pointer to a function without the if:
void foo_init(void);
void foo_real(void);
void (*foo)(void) = foo_init;
void foo_init(void) {
foo = foo_real;
/* do something only once */
foo_real();
}
void foo_real(void) {
/* something something... */
}
int main() {
foo();
foo();
}
Make foo and fooFirst, and then call like this
fooFirst();
for (...) {
foo();
}
foo and fooFirst can share code.
I have a requirement in C similar to function overriding. I have 2 devices with different device IDs. I have a process which just calls device_create(device_id). The process doesn't know which device_create to call. It is upto driver of the device to execute device_create if the device_id matches to driver's device Id. Is there any way to do it in C?
If you use different shared objects (or dlls) to implement the function you could handle this programatically on your own. You could create a plugin like structure and use something like the Command pattern.
Not exactly simple, but can help with your problem.
Cheers.
OK. Understand I'm still of the mark, but leave this post for now.
You do not know the ID when process starts. When HW is attached you read the ID and want to call correct function based on the ID but without using the ID directly?
The closest I can think of as a simple solution is by using an array of function pointers:
void (*funs[3])(void) = {
&device_create100,
&device_create200,
NULL
};
But then only if you can normalize the ID to match index of the array. Say all ID's are in the range 1000-1032 that would be an 32 long function pointer array where you can use ID - 1000.
As this is rather unlikely you could resort to a sorted list, binary tree, hash table or the like on which you do a lookup.
struct node {
int (*fun)(void);
int id;
struct *node left;
struct *node right;
}
This is of course then assuming you have a rather big list of possible ID's and a switch is out of the question.
Old post.
What about function pointers:
int (*device_create)(int);
int device_create_init(int id)
{
switch (id) {
case 0x0a:
device_create = &device_create_100;
break;
case 0x0b:
device_create = &device_create_200;
break;
}
/* After first call, the now set device_create_xxx function will be
invoked on device_create() */
return device_create(id);
}
int main(void)
{
device_create = &device_create_init;
/* Loop */
return 0;
}
I am in the middle of writing a program which has a function which runs another function:
int executePuzzle(int input) {
switch (input) {
case 1: puzzle1();break;
case 2: puzzle2();break;
default:break;
}
}
However it may be more efficient to simply have something like:
int puzzle[2] = {puzzle1(),puzzle2()};
Then call puzzle0; I was wondering how this would be done.
It sounds like a place where function pointers would be useful
typedef void (*puzzlePointer)();
puzzlePointer puzzles[] = { puzzle1, puzzle2, puzzle3 };
void executePuzzle(int input) {
if (input >= 0 && input < 2) {
puzzles[input]();
}
}
Use the Function Pointers
When the cases of the switch statement are contiguous like in your executePuzzle function, it is actually likely that the compiler internally uses function pointers (through a jump table) to implement the switch statement.
I'm sure some variation of this question has been asked before but all other, similar questions on SO seem to be much more complex, involving passing arrays and other forms of data. My scenario is much simpler so I hope there is a simple/elegant solution.
Is there a way that I can create an anonymous function, or pass a line of code as a function pointer to another function?
In my case, I have a series of diverse operations. Before and after each line of code, there are tasks I want to accomplish, that never change. Instead of duplicating the beginning code and ending code, I'd like to write a function that takes a function pointer as a parameter and executes all of the code in the necessary order.
My problem is that it's not worth defining 30 functions for each operation since they are each one line of code. If I can't create an anonymous function, is there a way that I can simplify my C code?
If my request isn't entirely clear. Here's a bit of pseudo-code for clarification. My code is much more meaningful than this but the code below gets the point accross.
void Tests()
{
//Step #1
printf("This is the beginning, always constant.");
something_unique = a_var * 42; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
//Step #2
printf("This is the beginning, always constant.");
a_diff_var = "arbitrary"; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
...
...
//Step #30
printf("This is the beginning, always constant.");
var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
}
Not in the traditional sense of anonymous functions, but you can macro it:
#define do_something(blah) {\
printf("This is the beginning, always constant.");\
blah;\
printf("End code, never changes");\
a_var++;\
}
Then it becomes
do_something(something_unique = a_var * 42)
No, you cannot. Anonymous functions are only available in functional languages (and languages with functional subsets), and as we all know, c is dysfunctional ;^)
In C and pre-0x C++, no.
In C++0x, yes, using lambda functions.
The best way to simplify your code would probably to put a for loop around a switch statement.
int a_var;
for ( a_var = 0; a_var <= 30; a_var++ )
{
starteroperations();
switch (a_var)
{
case 0:
operation0(); break;
case ...:
operationx(); break;
case 30:
...
}
closingoperations();
}
If you can use Clang, you can take advantage of blocks. To learn blocks, you can use Apple's documentation, Clang's block language specification and implementation notes, and Apple's proposal to the ISO C working group to add blocks to the standard C language, as well as a ton of blog posts.
Using blocks, you could write:
/* Block variables are declared like function pointers
* but use ^ ("block pointer") instead of * ("normal pointer"). */
void (^before)(void) = void ^(void) { puts("before"); };
/* Blocks infer the return type, so you don't need to declare it
* in the block definition. */
void (^after)(void) = ^(void) { puts("after"); };
/* The default arguments are assumed to be void, so you could even
* just define after as
*
* ^{ puts("after"); };
*/
before();
foo = bar + baz*kablooie;
after();
This example gives the anonymous blocks names by assigning to a block variable. You can also define and call a block directly:
^{ puts("!"); } ();
/*| definition | invocation of anonymous function |*/
This also makes defining "struct-objects" (OOP in C using structs) very simple.
Both Clang and GCC support inner/nested functions as an extension to standard C. This would let you define the function immediately before taking its address, which might be an alternative if your control flow structure allows it: inner function pointers cannot be allowed to escape from their immediate scope. As the docs say:
If you try to call the nested function through its address after the containing function has exited, all hell will break loose. If you try to call it after a containing scope level has exited, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.
Using nested functions, you could write:
/* Nested functions are defined just like normal functions.
* The difference is that they are not defined at "file scope"
* but instead are defined inside another function. */
void before(void) { puts("before"); };
void after(void) { puts("after"); };
before();
foo = bar + baz*kablooie;
after();
Either you go the case way suggested by #dcpomero, or you do the following:
typedef void job(int);
job test1; void test1(int a_var) { something_unique = a_var * 42; }
job test2; void test2(int a_var) { a_diff_var = "arbitrary"; }
job test3; void test3(int a_var) { var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; }
job * tests[] = { test1, test2, test3, testn };
void Tests()
{
int i;
for (i=0; i < sizeof tests/sizeof tests[0]; i++) {
printf("This is the beginning, always constant.");
tests[i](a_var);
printf("End code, never changes");
a_var++;
}
}
On a software project (some old C compiler) we have a lot of variables which have to be saved normal and inverted.
Has somebody a idea how i can make a macro like that?
SET(SomeVariable, 137);
which will execute
SomeVariable = 137;
SomeVariable_inverse = ~137;
Edit:
The best Solution seems to be:
#define SET(var,value) do { var = (value); var##_inverse = ~(value); } while(0)
Thanks for the answers
Try this
#define SET(var,value) do { var = (value); var##_inverse = ~(value); } while(0)
EDIT
Couple of links to the reason behind adding a do/while into the macro
https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
http://www.rtems.com/ml/rtems-users/2001/august/msg00111.html
http://c2.com/cgi/wiki?TrivialDoWhileLoop
http://blogs.msdn.com/jaredpar/archive/2008/05/21/do-while-0-what.aspx
One hazard I haven't seen mentioned is that the 'value' macro argument is evaluated twice in most of the solutions. That can cause problems if someone tries something like this:
int x = 10;
SET(myVariable, x++);
After this call, myVariable would be 10 and myVariable_inverse would be ~11. Oops. A minor change to JaredPar's solution solves this:
#define SET(var,value) do { var = (value); var##_inverse = ~(var); } while(0)
Why are you storing the inverse when it can be so easily calculated? This seems like a bad idea to me.
You can do it in a single statement, which avoids having to use do {} while (0).
#define SetInverse(token, value) (token##_inverse = ~(token = (value)))
Also, this only evalutes (value) once, which is always nice.
#define SetInverse(token, value) { token = value; token##_inverse = ~value; }
Jinx, Jared - like the while (0) in yours
Just to offer an alternative method:
Store each variable as a structure like this:
typedef struct
{
u32 u32Normal;
u32 u32Inverted;
} SafeU32TYPE
Then have a function which takes a pointer to one of these, along with the value to be set, and stores that value with its inverse:
void Set(SafeU32TYPE *pSafeU32, u32Data)
{
if(pSafeU32 != NULL)
{
pSafeU32->u32Normal = u32Data;
pSageU32->u32Inverted = ~u32Data;
} /* if */
} /* Set() */
Advantage: if you need the set function to do something more powerful, such as boundary checking, or storing in some more complex way, then it can be easily extended.
Disadvantage: you'll need a different function for each type used, and if processor resource is an issue, this is less efficient than using a macro.