I found this piece of code on GitHub but didn't quite understand it:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Then:
int (*max)(int, int) = lambda(int,
(int x, int y) {
return x > y ? x : y;
});
int max_value = max(1, 2);
// max_value is 2
What are the underscores doing inside the #define
and how does it return a function pointer?
Using this macro,
int (*max)(int, int) = lambda(int,
(int x, int y) {
return x > y ? x : y;
});
expands to:
int (*max)(int, int) = ({
int _ (int x, int y) { return x > y ? x : y; }
_;
});
In the curly braces, this uses GCC's Nested Functions to create a function that performs the desired operation. Within the inner scope, it has the name _
.
Then, as noted by interjay, GCC's Statement Expressions are used. Effectively, the function _
is assigned to the pointer max
.
If such a macro isn't being used, this could be written differently and used as:
int val1 = 4;
int val2 = -30;
int perform_operation(int (*op)(int, int)) {
int new_val = op(val1, val2);
val1 = val2;
val2 = new_val;
return new_val;
}
int enclosing_function (void) {
// Create max "lambda"
int (*max)(int, int);
{
// Curly braces limit the scope of _
int _ (int x, int y) { return x > y ? x : y; }
max = _;
}
return perform_operation(max);
}
The three methods can be compared in this code example.
This is called a statement expression and creates a "lambda" (or nested function) and returns a pointer to it. It is GNU C-specific.
The macro expands to:
int (*max)(int, int) = ({ int _ (int x, int y) { return x > y ? x : y; } _; })
The _
at the end is like a return
.
The underscore is actually the name of the function that is created and "returned". It's used because it's an uncommonly-used identifier (for good reason; _
is quite possibly the least descriptive identifier possible).
The reason the statement expression is used is so _
won't be defined after the scope of the statement expression exits.
So, going through the macro:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
ret_type
is the return type of the "lambda". _
is the name of the function used inside it because it is an uncommon identifier name. _body
consists of the arguments and body of the function. The trailing _
"returns" the "lambda".
This code is found at Let's Destroy C (which is an appropriate name). You shouldn't use it. It will make your code work only on compilers that support GNU C extensions. Instead, just write a function or macro.
If you use constructs like this a lot or want more features, I suggest using C++. With C++ you can do something similar to this and have portable code.
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