I ran into some code on GitHub. https://github.com/codeplea/tinyexpr/blob/master/tinyexpr.c
These lines caught my eye:
static double pi(void) {return 3.14159265358979323846;}
static double e(void) {return 2.71828182845904523536;}
Is there any reason at all to use functions in this case? Why not use constants? You could use preprocessor macros, but that can make debugging harder. I have never seen this before. Is there any benefit of this?
The main reason I can think of is to make it easier to search for where that constant is used. For example, you search for e(
instead of e
.
That isn't the case here, however. The functions are being used, but not called explicitly.
The linked code contains an array of structs:
typedef struct te_variable {
const char *name;
const void *address;
int type;
void *context;
} te_variable;
...
static const te_variable functions[] = {
/* must be in alphabetical order */
{"abs", fabs, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"acos", acos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"asin", asin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"atan", atan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"atan2", atan2, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"ceil", ceil, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"cos", cos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"cosh", cosh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"e", e, TE_FUNCTION0 | TE_FLAG_PURE, 0},
{"exp", exp, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"floor", floor, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"ln", log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#ifdef TE_NAT_LOG
{"log", log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#else
{"log", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#endif
{"log10", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"ncr", ncr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"npr", npr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"pi", pi, TE_FUNCTION0 | TE_FLAG_PURE, 0},
{"pow", pow, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"sin", sin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"sinh", sinh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"sqrt", sqrt, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"tan", tan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"tanh", tanh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{0, 0, 0, 0}
};
The second member of each struct is a function pointer used to run some math related function, and the values of E and PI are among them. So it looks like they were defined as functions to conform to this framework.
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