I recently started a small personal project (RGB value to BGR value conversion program) in C, and I realised that a function that converts from RGB to BGR can not only perform the conversion but also the inversion. Obviously that means I don't really need two functions rgb2bgr
and bgr2rgb
. However, does it matter whether I use a function pointer instead of a macro? For example:
int rgb2bgr (const int rgb);
/*
* Should I do this because it allows the compiler to issue
* appropriate error messages using the proper function name,
* not to mention possible debugging benefits?
*/
int (*bgr2rgb) (const int bgr) = rgb2bgr;
/*
* Or should I do this since it is merely a convenience
* and they're really the same function anyway?
*/
#define bgr2rgb(bgr) (rgb2bgr (bgr))
I'm not necessarily looking for a change in execution efficiency as it's more of a subjective question out of curiosity. I am well aware of the fact that type safety is neither lost nor gained using either method. Would the function pointer merely be a convenience or are there more practical benefits to be gained of which I am unaware?
The speed at which macros and functions differs. Macros are typically faster than functions as they don't involve actual function call overhead.
In the case of inline, the arguments are evaluated only once. Whereas in the case of macro, the arguments are evaluated every time whenever macro is used in the program.
Using a function pointer is slower that just calling a function as it is another layer of indirection. (The pointer needs to be dereferenced to get the memory address of the function). While it is slower, compared to everything else your program may do (Read a file, write to the console) it is negligible.
5) Function pointer can be used in place of switch case. For example, in below program, user is asked for a choice between 0 and 2 to do different tasks. 6) Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function.
Another possibility would be to just have the second function call the first and let the compiler worry about optimizing it (by inlining or generating a tail call).
I would use the macro. It's more common and more idiomatic, and runs into fewer problems crossing translation units (i.e. you don't have to worry about declaring the macro static).
Additionally, by using a function pointer, you prevent inlining on most compilers.
Finally, with the function pointer, it's possible for clients to do this:
int evil(const int bgr) { /* Do something evil */ }
bgr2rgb = evil
Sure, they probably don't want this, but it's possible there could be a variable named similar to bgr2rgb
down the line where it only takes one typo....
The macro is safer, though I would define it this way -- there's no need for a function-like macro here:
#define bgr2rgb rgb2bgr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With