I'd like to declare the following function with multiple names:
static __inline__ int square(int i) {
return i * i;
}
It only has to work with GCC 4.x (for some useful value of x)
I've tried __asm__, but it works for non-static functions only, so this doesn't work:
static __inline__ int square2(int i) __asm__("square");
I've tried alias, but it prevents the call to square2 from being inlined, but I want inlining for both square and square2, equivalently.
static __inline__ int square2(int i) __attribute__((alias("square2")));
I've tried a macro, but that prevents me from using independent local variables named square and square2 in other unrelated functions. So I can't accept this:
#define square2 square
I know about writing another call, but I don't like it, because it's one more indirection for the optimizer, and it may prevent inlining in some complicated case:
static __inline__ int square2(int i) { return square(i); }
Is there another solution?
I guess your "real" code has a more complicated function than a single statement? Else the obvious choice is to repeat the definition with the second name.
You could make it a macro, of course:
#define SQUARE_BODY(a) return (a) * (a);
static inline square(int x)
{
SQUARE_BODY(x);
}
static inline square2(int x)
{
SQUARE_BODY(x);
}
Of course you can fold more of the function definitions into the macro, but I think that having it only be the body part makes the rest of the code clearer.
Related
I have multiple functions that are similar to each other - they take in the same arguments, and return the same type:
double mathFunction_1(const double *values, const size_t array_length);
I already use typedef'd pointers to those functions, as I store them as an array to easily use any number of them on the same data, map them etc.:
typedef double (* MathFunction_ptr )(const double *, const size_t);
double proxy(MathFunction_ptr mathfun_ptr, const double *values, const size_t array_length);
What I want to achieve, is a similar ease-of-use with declaring and defining the functions, as I already have with using pointers to them.
Thus, I was thinking about using a similar typedef to make it easier for me to write the actual functions. I tried doing it like this:
// declaration
typedef double MathFunction (const double *values, const size_t array_length);
MathFunction mathFunction_2;
The following approach works partially. It lets me "save a few keystrokes" in the declaration, however the definition has to be fully typed out.
double mathFunction_2(const double *values, const size_t array_length)
{
// ...
}
What I found by searching more for this issue is this: Can a function prototype typedef be used in function definitions?
However it doesn't provide many alternatives, and only reaffirms that what I tried to do in my other experiments is forbidden according to the Standard. The only alternative it provides is using
#define FUNCTION(name) double name(const double* values, size_t array_length)
which sounds clunky to me(as I'm wary and skeptical of using the preprocessor).
What are the alternatives to what I'm trying to do?
Two other approaches I tried that don't work(and, as I just read, are forbidden and absolutely wrong according to the C standard 6.9.1):
1.This approach doesn't work, as it means that I'm telling it to define a variable mathFunction_2(I believe that variable is treated as a pointer, though I don't understand this well enough yet) like a function:
MathFunction mathFunction_2
{
// ...
}
2.This approach doesn't work, as it means I'm telling it to create a function which returns a function(unacceptable in the C language):
MathFunction mathFunction_2()
{
// ...
}
You could use a typedef for the signature (see also this):
typedef double MathFunction_ty (const double *, const size_t);
and then declare several functions of the same signature:
MathFunction_ty func1, func2;
or declare some function pointer using that:
MathFunction_ty* funptr;
etc... All this in C11, read n1570.
however the definition has to be fully typed out.
Of course, since you need to give a name to each formal parameter (and such names are not part of the type of the function) in the function's definition. Therefore
double func1(const double*p, const size_t s) {
return (double)s * p[0];
}
and
double func1(cont double*arr, const size_t ix) {
return arr[ix];
}
have the same type (the one denoted by MathFunction_ty above), even if their formal parameters (or formal arguments) are named differently.
You might abuse of the preprocessor and have an ugly macro to shorten the definition of such functions:
// ugly code:
#define DEFINE_MATH_FUNCTION(Fname,Arg1,Arg2) \
double Fname (const double Arg1, const size_t Arg2)
DEFINE_MATH_FUNCTION(func1,p,s) { return (double)s * p[0]; }
I find such code confusing and unreadable. I don't recommend coding like that, even if it is certainly possible. But sometimes I do code something similiar (for other reasons).
(BTW, imagine if C required every first formal argument to be named $1, every second formal argument to be named $2, etc...; IMHO that would make a much less readable programming langage; so formal parameter's name matters to the human reader, even if systematic names would make the compiler's life simpler)
Read also about λ-calculus, anonymous functions (C don't have them but C++ has lambda expressions), closures (they are not C functions, because they have closed values so mix code with data; C++ has std::function-s), callbacks (a necessary convention to "mimick" closures)... Read SICP, it will improve your thinking about C or C++. Look also into that answer.
Unfortunately in C I don't believe there is any way to do what you're asking without using preprocessor macros, and personally at least I agree with your assessment that they are clunky and to be avoided (though this is a matter of opinion and open to debate).
In C++ you could potentially take advantage of auto parameters in lambdas.
The example function signatures you show here really aren't complicated and I wouldn't worry about the perceived duplication. If the signatures were much more complicated, I would view this as a "code smell" that your design could be improved, and I'd focus my efforts there rather than on syntactic methods to shorten the declaration. That just isn't the case here.
Yes, you can. Indeed, that's the purpose of the typedef declaration, to use a type identifier to declare a type of variable. The only thing is that when you use such a declaration in a header file:
typedef int (*callback_ptr)(int, double, char *);
and then you declare something like:
callback_ptr function_to_callback;
it's not clear that you are declaring a function pointer and the number and type of the parameters, but despite of this, everything is correct.
Finally, I want to note you something particularly special. When you deal with something like this, it is normally far cheaper and quick to go to the compiler and try some example. If the compiler does what you want without any complaint, the most probable thing is that you are correct.
#include <stdio.h>
#include <math.h>
typedef double (*ptr_to_mathematical_function)(double);
extern double find_zero(ptr_to_mathematical_function f, double aprox_a, double aprox_b, double epsilon);
int main()
{
#define P(exp) printf(#exp " ==> %lg\n", exp)
P(find_zero(cos, 1.4, 1.6, 0.000001));
P(find_zero(sin, 3.0, 3.2, 0.000001));
P(find_zero(log, 0.9, 1.5, 0.000001));
}
double find_zero(
ptr_to_mathematical_function f,
double a, double b, double eps)
{
double f_a = f(a), f_b = f(b);
double x = a, f_x = f_a;
do {
x = (a*f_b - b*f_a) / (f_b - f_a);
f_x = f(x);
if (fabs(x - a) < fabs(x - b)) {
b = x; f_b = f_x;
} else {
a = x; f_a = f_x;
}
} while(fabs(a-b) >= eps);
return x;
}
The second, and main part of your question, if you are having such a problem, the only way you can solve it is via using macros (see how I repeated the above printf(3) function calls with similar, but not identical parameter lists, and how the problem is solved below):
#define MY_EXPECTED_PROTOTYPE(name) double name(double x)
and then, in the definitions, just use:
MY_EXPECTED_PROTOTYPE(my_sin) {
return sin(x);
}
MY_EXPECTED_PROTOTYPE(my_cos) {
return cos(x);
}
MY_EXPECTED_PROTOTYPE(my_tan) {
return tan(x);
}
...
that will expand to:
double my_sin(double x) {
...
double my_cos(double x) {
...
double my_tan(double x) {
...
you can even use it in the header file, like:
MY_EXPECTED_PROTOTYPE(my_sin);
MY_EXPECTED_PROTOTYPE(my_cos);
MY_EXPECTED_PROTOTYPE(my_tan);
As it has been pointed in other answers, there are other languages (C++) that give support for this and much more, but I think this is out of scope here.
In file1.h
// find the root of a function of one variable
double rootfind(double (*fp)(double), double start, double end);
In file2.h
// a function of multiple variables
double myfun(double a, double b);
double test();
In file2.c
double myfun(double a, double b)
{
return (a+3.0)*(a-1.0)*(a-1.0)*b;
}
double test()
{
double b, start, end;
start = -4.0;
end = 4.0/3.0;
b = 2.0;
// How do I use the rootfinding function to find the root of myfun
// where b is set as a constant in this function?
// How do i find the root of myfun(x,2.0)?
}
I want to keep the rootfind function generic and not pass extra parameters in. I also don't want to use the gcc extension for nested functions.
You are asking about something known as closures which are not supported in standard C90/C99. If you do plan on doing this, you either have to:
Use the GCC extension you mentioned.
Use C++'s std::bind function.
Use a library (such as libffi that comes with GCC) to allocate memory that can be written to and run (you create the machine code for the new one argument function at runtime).
Write a top level static function that works the way you want it to.
Use a dynamically loaded module that you compile from C code at runtime.
Most of those probably seem confusing/intimidating, that's because there's really no good way to do what you want in C. This is mostly because it's very dangerous (major security hole) to have functions rewritten at run time in C.
An example of a top level static function (place this just above your main function):
static myfun_single_b = 2.0;
static double myfun_single(double a) {
return myfun(a, myfun_single_b);
}
The reason we use the static keyword here is so that the name of the variable and the name of the function won't conflict with other function/variable names from other source files.
You can write a wrapper function:
static double wrapper(double a) {
return myfun(a, 3.0);
}
and use rootfind() on that. You could make it more general (i.e. to support different values of the second argument to myfun()) by making it take the value of myfun()'s second argument from a file-scope variable:
static double b;
static double wrapper(double a) {
return myfun(a, b);
}
You could even generalize it more by making the wrapper call a two-arg function via a file-scope function pointer:
static double b;
static double (*wrapped)(double, double);
static double wrapper(double a) {
return (*wrapped)(a, b);
}
That's about the limit of the indirection you can perform, but it affords a fair amount of latitude.
If you can modify rootfind, the proper way to fix it would be to add a context parameter to the function pointer, like
double rootfind(double (*fp)(double, void *), double start, double end, void *context);
You can then create a context struct containing your second argument b and pass a pointer to it via the context argument.
This way, both global state and run-time code generation are avoided. The rootfind function also remains generic.
Can the name of function and function-like macro be same?
Wouldn't this cause any problem?
They could be the same. Depending on how you use the name, either it gets replaced by preprocessor or not. For example
//silly but just for demonstration.
int addfive(int n)
{
return n + 5;
}
#define addfive(n) ((n) + 5)
int main(void)
{
int a;
a = addfive(2); //macro
a = (addfive)(2); //function
}
for ex. MS says that: http://msdn.microsoft.com/en-us/library/aa272055(v=vs.60).aspx
http://gcc.gnu.org/onlinedocs/cpp/Function-like-Macros.html#Function-like-Macros
Here you can see that calling the function, of which a macro with the same name exists, calls the macro instead :)
For the gcc at least!
This would cause no problem, but quite some confusions. I wouldn't recommend this.
I will explain via cases:
If you declared the function first then the function like macro second, macro will over take the function. i.e. it will be called always instead of the function.
//Function
double squar(double x)
{
return x*x;
}
//Macro
#define squar(x) (x*x)
On the other hand if you declare the macro first then the function later, an exception will be arise, you wont be able to build
//Macro
#define squar(x) (x*x)
//Function
double squar(double x)
{
return x*x;
}
At the end, in the first case, you still call the function like #Hayri Uğur Koltuk said here in his answer by (squar)(5)
I have a function that I need to macro'ize. The function contains temp variables and I can't remember if there are any rules about use of temporary variables in macro substitutions.
long fooAlloc(struct foo *f, long size)
{
long i1, i2;
double *data[7];
/* do something */
return 42;
}
MACRO Form:
#define ALLOC_FOO(f, size) \
{\
long i1, i2;\
double *data[7];\
\
/* do something */ \
}
Is this ok? (i.e. no nasty side effect - other than the usual ones : not "type safe" etc). BTW, I know "macros are evil" - I simply have to use it in this case - not much choice.
There are only two conditions under which it works in any "reasonable" way.
The macro doesn't have a return statement. You can use the do while trick.
#define macro(x) do { int y = x; func(&y); } while (0)
You only target GCC.
#define min(x,y) ({ int _x = (x), _y = (y); _x < _y ? _x : _y; })
It would help if you explain why you have to use a macro (does your office have "macro mondays" or something?). Otherwise we can't really help.
C macros are only (relatively simple) textual substitutions.
So the question you are maybe asking is: can I create blocks (also called compound statements) in a function like in the example below?
void foo(void)
{
int a = 42;
{
int b = 42;
{
int c = 42;
}
}
}
and the answer is yes.
Now as #DietrichEpp mentioned it in his answer, if the macro is a compound statement like in your example, it is a good practice to enclose the macro statements with do { ... } while (0) rather than just { ... }. The link below explains what situation the do { ... } while (0) in a macro tries to prevent:
http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Also when you write a function-like macro always ask yourself if you have a real advantage of doing so because most often writing a function instead is better.
First, I strongly recommend inline functions. There are very few things macros can do and they can't, and they're much more likely to do what you expect.
One pitfall of macros, which I didn't see in other answers, is shadowing of variable names.
Suppose you defined:
#define A(x) { int temp = x*2; printf("%d\n", temp); }
And someone used it this way:
int temp = 3;
A(temp);
After preprocessing, the code is:
int temp = 3;
{ int temp = temp*2; printf("%d\n", temp); }
This doesn't work, because the internal temp shadows the external.
The common solution is to call the variable __temp, assuming nobody will define a variable using this name (which is a strange assumption, given that you just did it).
This is mostly OK, except that macros are usually enclosed with do { ... } while(0) (take a look at this question for explanations):
#define ALLOC_FOO(f, size) \
do { \
long i1, i2;\
double *data[7];\
/* do something */ \
} while(0)
Also, as far as your original fooAlloc function returns long you have to change your macro to store the result somehow else. Or, if you use GCC, you can try compound statement extension:
#define ALLOC_FOO(f, size) \
({ \
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Finally you should care of possible side effects of expanding macro argument. The usual pattern is defining a temporary variable for each argument inside a block and using them instead:
#define ALLOC_FOO(f, size) \
({ \
typeof(f) _f = (f);\
typeof(size) _size = (size);\
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Eldar's answer shows you most of the pitfalls of macro programming and some useful (but non standard) gcc extension.
If you want to stick to the standard, a combination of macros (for genericity) and inline functions (for the local variables) can be useful.
inline
long fooAlloc(void *f, size_t size)
{
size_t i1, i2;
double *data[7];
/* do something */
return 42;
}
#define ALLOC_FOO(T) fooAlloc(malloc(sizeof(T)), sizeof(T))
In such a case using sizeof only evaluates the expression for the type at compile time and not for its value, so this wouldn't evaluate F twice.
BTW, "sizes" should usually be typed with size_t and not with long or similar.
Edit: As to Jonathan's question about inline functions, I've written up something about the inline model of C99, here.
Yes it should work as you use a block structure and the temp variables are declared in the inner scope of this block.
Note the last \ after the } is redundant.
A not perfect solution: (does not work with recursive macros, for example multiple loops inside each other)
#define JOIN_(X,Y) X##Y
#define JOIN(X,Y) JOIN_(X,Y)
#define TMP JOIN(tmp,__LINE__)
#define switch(x,y) int TMP = x; x=y;y=TMP
int main(){
int x = 5,y=6;
switch(x,y);
switch(x,y);
}
will become after running the preprocessor:
int main(){
int x=5,y=6;
int tmp9 = x; x=y; y=tmp9;
int tmp10 = x; x=y; y=tmp10;
}
They can. They often shouldn't.
Why does this function need to be a macro? Could you inline it instead?
If you're using c++ use inline, or use -o3 with gcc it will inline all functions for you.
I still don't understand why you need to macroize this function.
void (assert)(int e)
{
assert(e);
}
How does it work here?
void (assert)(int e) is equivalent to void assert(int)
Why would you need it?
Consider the following example
#include<stdio.h>
void foo(int a)
{
printf("%d", a);
}
#define foo(a) {/*I do nothing*/}
int main()
{
foo(5); // won't call `foo`
}
How would you make sure when you call foo, its the function that is called and not the macro-definition substituted at the place of call?
The solution is to put an extra parenthesis like (foo)(5)
Similarly assert is already known to be a macro. That's the reason I can think of.
Since assert already is defined as a function-style macro, without the parentheses it would have been expanded both in the function header and in the body.
For example:
#define twice(x) ((x)+(x))
void twice(int i)
{
return twice(i);
}
Will expand to the following, which clearly is not legal
void ((int i)+(int i))
{
return ((i)+(i));
}
On the other hand:
#define twice(x) ((x)+(x))
void (twice)(int i)
{
return twice(i);
}
Will expand to:
void (twice)(int i)
{
return ((i)+(i));
}
The extra parentheses around the function name is simply ignored by the compiler.
This is a common trick often used in the source of the standard library, on in other contexts where there might be functions and macros with the same name.
It's legal syntax, just writing it with extra parentheses. The reason you'd do that is because assert() is often defined as a macro; so the above function exists to make assert() be a real function, probably so you can set a breakpoint in it.