This behavior seems to be specfic to newer versions of Clang, and is a language extension called "blocks".
The Wikipedia article on C "blocks" also provides information which supports this claim:
Blocks are a non-standard extension added by Apple Inc. to Clang's implementations of the C, C++, and Objective-C programming languages that uses a lambda expression-like syntax to create closures within these languages. Blocks are supported for programs developed for Mac OS X 10.6+ and iOS 4.0+, although third-party runtimes allow use on Mac OS X 10.5 and iOS 2.2+ and non-Apple systems.
Emphasis above is mine. On Clang's language extension page, under the "Block type" section, it gives a brief overview of what the Block type is:
Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.
GCC also has something similar to blocks called lexically scoped nested functions. However, there are some key differences also note in the Wikipedia articles on C blocks:
Blocks bear a superficial resemblance to GCC's extension of C to support lexically scoped nested functions. However, GCC's nested functions, unlike blocks, must not be called after the containing scope has exited, as that would result in undefined behavior.
GCC-style nested functions also require dynamic creation of executable thunks when taking the address of the nested function. [...].
Emphasis above is mine.
Answer from Chris on Stack OverflowThis behavior seems to be specfic to newer versions of Clang, and is a language extension called "blocks".
The Wikipedia article on C "blocks" also provides information which supports this claim:
Blocks are a non-standard extension added by Apple Inc. to Clang's implementations of the C, C++, and Objective-C programming languages that uses a lambda expression-like syntax to create closures within these languages. Blocks are supported for programs developed for Mac OS X 10.6+ and iOS 4.0+, although third-party runtimes allow use on Mac OS X 10.5 and iOS 2.2+ and non-Apple systems.
Emphasis above is mine. On Clang's language extension page, under the "Block type" section, it gives a brief overview of what the Block type is:
Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.
GCC also has something similar to blocks called lexically scoped nested functions. However, there are some key differences also note in the Wikipedia articles on C blocks:
Blocks bear a superficial resemblance to GCC's extension of C to support lexically scoped nested functions. However, GCC's nested functions, unlike blocks, must not be called after the containing scope has exited, as that would result in undefined behavior.
GCC-style nested functions also require dynamic creation of executable thunks when taking the address of the nested function. [...].
Emphasis above is mine.
the C standard does not define lambdas at all but the implementations can add extensions.
Gcc also added an extension in order for the programming languages that support lambdas with static scope to be able to convert them easily toward C and compile closures directly.
Here is an example of extension of gcc that implements closures.
#include <stdio.h>
int(*mk_counter(int x))(void)
{
int inside(void) {
return ++x;
}
return inside;
}
int
main() {
int (*counter)(void)=mk_counter(1);
int x;
x=counter();
x=counter();
x=counter();
printf("%d\n", x);
return 0;
}
c++ - What is a lambda, and why would it be useful? - Software Engineering Stack Exchange
simple lambda like functions in C
c++ - What is a lambda expression, and when should I use one? - Stack Overflow
Why does C not have lambdas/anonymous function expressions?
Videos
It would not seem to hard to implement to allow a programmer to use a construct similar to:
int (*add)(int, int) = (int(int x, int y)){return x+y;};
This would simplify code that requires callback functions such as qsort or bsearch or various UI libraries that use callbacks to define, for example, a buttons behavior when pressed. Is there any specific reason they elected not to support this, and require us to define named static functions instead?
- Lambda calculus
The lambda calculus is a computation model invented by Alonzo Church in the 30s. The syntax and semantics of most functional programming languages are directly or indirectly inspired by the lambda calculus.
The lambda calculus in its most basic form has two operations: Abstraction (creating an (anonymous) function) and application (apply a function). Abstraction is performed using the λ operator, giving the lambda calculus its name.
- Lambda expressions
- Lambda functions
Anonymous functions are often called "lambdas", "lambda functions" or "lambda expressions" because, as I said above, λ was the symbol to create anonymous functions in the lambda calculus (and the word lambda is used to create anonymous functions in many lisp-based languages for the same reason).
- Lambda programming
This is not a commonly used term, but I assume it means programming using anonymous functions or programming using higher-order functions.
A bit more information about lambdas in C++0x, their motivation and how they relate to function pointers (a lot of this is probably a repeat of what you already know, but I hope it helps explain the motivation of lambdas and how they differ from function pointers):
Function pointers, which already existed in C, are quite useful to e.g. pass a comparison function to a sorting function. However there are limits to their usefulness:
For example if you want to sort a vector of vectors by the ith element of each vector (where i is a run-time parameter), you can't solve this with a function pointer. A function that compares two vectors by their ith element, would need to take three arguments (i and the two vectors), but the sorting function would need a function taking two arguments. What we'd need is a way to somehow supply the argument i to the function before passing it to the sorting function, but we can't do this with plain C functions.
To solve this, C++ introduced the concept of "function objects" or "functors". A functor is basically an object which has an operator() method. Now we can define a class CompareByIthElement, which takes the argument i as a constructor argument and then takes the two vectors to be compared as arguments to the operator() method. To sort a vector of vectors by the ith element we can now create a CompareByIthElement object with i as an argument and then pass that object to the sorting function.
Since function objects are just objects and not technically functions (even though they are meant to behave like them), you can't make a function pointer point to a function object (you can of course have a pointer to a function object, but it would have a type like CompareByIthElement* and thus not be a function pointer).
Most functions in the C++ standard library which take functions as arguments are defined using templates so that they work with function pointers as well as function objects.
Now to lambdas:
Defining a whole class to compare by the ith element is a bit verbose if you're only ever going to use it once to sort a vector. Even in the case where you only need a function pointer, defining a named function is sub-optimal if it's only used once because a) it pollutes the namespace and b) the function is usually going to be very small and there isn't really a good reason to abstract the logic into its own function (other than that you can't have function pointers without defining a function).
So to fix this lambdas were introduced. Lambdas are function objects, not function pointers. If you use a lambda literal like x1, x2{bla} code is generated which basically does the following:
- Define a class which has two member variables (
x1andx2) and anoperator()with the arguments (y1andy2) and the bodybla. - Create an instance of the class, setting the member variables
x1andx2to the values of the variablesx1andx2currently in scope.
So lambdas behave like function objects, except that you can't access the class that's generated to implement a lambda in any way other than using the lambda. Consequently any function that accepts functors as arguments (basically meaning any non-C function in the standard library), will accept lambdas, but any function only accepting function pointers will not.
Basically, lambda functions are functions you create "on the fly". In C++1x they could be used to improve on its support for functional programming:
std::for_each( begin, end, [](int i){std::cout << i << '\n';} );
This will roughly result in code similar to this one:
struct some_functor {
void operator()(int i) {std::cout << i << '\n';}
};
std::for_each( begin, end, some_functor() );
If you need some_functor just for this one call to std::for_each(), then that lambda function has several advantages over it:
- what's done in the loop is specified right where the looping function is called
- it relieves you from writing some of the boiler-plate code
- there's no functor lying around at some namespace scope that makes everyone looking at the code wondering what it is needed for
I was diving in reddit and I found the following post
I thought: maybe it is possible to do something similar in C with macros or something along those lines.
After some research, I found the following topic on GCC manual:
Statements and Declarations in Expressions
Well, with this construction, it's possible to instruct the compiler to define a function and call it in place, like we can do with lambdas. Look the example bellow:
#include <stdio.h>
int call_callback(void (*callback)()){
callback();
}
void foo() {
printf("foo\n");
}
int main(void) {
call_callback(foo);
call_callback(({
void _() {
printf("this is a lambda?\n");
}
(void (*)())_;
}));
}For me, it's very interesting. We encounter many situations and libraries that deal with callback functions, and personally, I often find myself declaring simple functions that are only called once. I believe that in these cases, this construct would work very well.
However, debugging it might be challenging.
The problem
C++ includes useful generic functions like std::for_each and std::transform, which can be very handy. Unfortunately they can also be quite cumbersome to use, particularly if the functor you would like to apply is unique to the particular function.
#include <algorithm>
#include <vector>
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
void func(std::vector<int>& v) {
f f;
std::for_each(v.begin(), v.end(), f);
}
If you only use f once and in that specific place it seems overkill to be writing a whole class just to do something trivial and one off.
In C++03 you might be tempted to write something like the following, to keep the functor local:
void func2(std::vector<int>& v) {
struct {
void operator()(int) {
// do something
}
} f;
std::for_each(v.begin(), v.end(), f);
}
however this is not allowed, f cannot be passed to a template function in C++03.
The new solution
C++11 introduces lambdas allow you to write an inline, anonymous functor to replace the struct f. For small simple examples this can be cleaner to read (it keeps everything in one place) and potentially simpler to maintain, for example in the simplest form:
void func3(std::vector<int>& v) {
std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}
Lambda functions are just syntactic sugar for anonymous functors.
Return types
In simple cases the return type of the lambda is deduced for you, e.g.:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; }
);
}
however when you start to write more complex lambdas you will quickly encounter cases where the return type cannot be deduced by the compiler, e.g.:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
To resolve this you are allowed to explicitly specify a return type for a lambda function, using -> T:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
"Capturing" variables
So far we've not used anything other than what was passed to the lambda within it, but we can also use other variables, within the lambda. If you want to access other variables you can use the capture clause (the [] of the expression), which has so far been unused in these examples, e.g.:
void func5(std::vector<double>& v, const double& epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
epsilon -> double {
if (d < epsilon) {
return 0;
} else {
return d;
}
});
}
You can capture by both reference and value, which you can specify using & and = respectively:
[&epsilon, zeta]captures epsilon by reference and zeta by value[&]captures all variables used in the lambda by reference[=]captures all variables used in the lambda by value[&, epsilon]captures all variables used in the lambda by reference but captures epsilon by value[=, &epsilon]captures all variables used in the lambda by value but captures epsilon by reference
The generated operator() is const by default, with the implication that captures will be const when you access them by default. This has the effect that each call with the same input would produce the same result, however you can mark the lambda as mutable to request that the operator() that is produced is not const.
What is a lambda expression?
The C++ concept of a lambda expression originates in the lambda calculus and functional programming. A lambda is an unnamed function that is useful (in actual programming, not theory) for short snippets of code that are impossible to reuse and are not worth naming.
In C++, the minimal lambda expression looks like:
[]{} // lambda with no parameters that does nothing
[] is the capture list and {} the function body.
The full syntax for a lambda-expression, including attributes, noexcept/throw-specifications, requires-clauses, etc. is more complex.
The capture list
The capture list defines what from the outside of the lambda should be available inside the function body and how. It can be either:
- a value:
[x] - a reference
[&x] - any variable currently in scope by reference
[&] - same as 3, but by value
[=] - capturing
thisand making member functions callable within the lambda[this]
You can mix any of the above in a comma separated list [x, &y].
Init-captures (C++14)
An element of the capture list can now be initialized with =, which is called init-capture.
This allows renaming of variables and to capture by moving. An example taken from the standard:
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2;
return x+2;
}(); // Updates ::x to 6, and initializes y to 7.
and one taken from Wikipedia showing how to capture with std::move:
auto ptr = std::make_unique<int>(10); // See below for std::make_unique
auto lambda = [ptr = std::move(ptr)] {return *ptr;};
The template parameters (C++20)
Since C++20, lambda expressions can have a template-parameter-list:
[]<int N>() {};
Such a generic lambda is like a non-template struct with a call operator template:
struct __lambda {
template <int N> void operator()() const {}
};
The parameter list
The parameter-declaration-clause is the same as in any other C++ function.
It can be omitted completely when there are no parameters, meaning that [](){} is equivalent to []{}.
Generic Lambdas (C++14)
Lambdas with an auto parameter are generic lambdas.
auto would be equivalent to T here if
T were a type template argument somewhere in the surrounding scope):
[](auto x, auto y) { return x + y; }
This works just like a C++20 abbreviated function template:
struct __lambda {
// C++20 equivalent
void operator()(auto x, auto y) const { return x + y; }
// pre-C++20 equivalent
template <typename T, typename U>
void operator()(T x, U y) const { return x + y; }
};
Return type (possibly deduced)
If a lambda has only one return statement, the return type can be omitted and has the implicit type of decltype(return_statement).
The return type can also be provided explicitly using trailing return type syntax:
[](int x) -> int { return x; }
Improved Return Type Deduction (C++14)
C++14 allows deduced return types for every function and does not restrict it to functions of the form return expression;. This is also extended to lambdas.
By default, the return type of a lambda is deduced as if its return type was declared auto.
Mutable lambda (C++14)
If a lambda is marked mutable (e.g. []() mutable { }) it is allowed to mutate the values that have been captured by value.
mutable means that the call operator of the lambda's type does not have a const qualifier.
The function body
A block-statement will be executed when the lambda is actually called. This becomes the body of the call operator.
Use cases
The library defined by the ISO standard benefits heavily from lambdas and raises the usability several bars as now users don't have to clutter their code with small functors in some accessible scope.