#include<iostream>
using namespace std;
int main()
{
const int k = 10;
// Capture k by value
auto myl = [k] (int k) { cout << " ++k=" << ++k ; };
myl(k+10);
}
Error below
lamda.cpp: In lambda function:
lamda.cpp:10:50: error: increment of read-only variable âkâ
auto myl = [k] (int k) { cout << " ++K=" << ++k ; };
clearly what I am referring to is local variable K and not const member K.
If you want to use clang instead of GCC, you can add -DCMAKE_C_COMPILER=/path/to/clang -DCMAKE_CXX_COMPILER=/path/to/clang++ . You can also use ccmake , which provides a curses interface to configure CMake variables.
Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.
Clang is a C, C++, Objective-C, or Objective-C++ compiler that is compiled in C++ based on LLVM and released under the Apache 2.0 license. Clang is mainly used to provide performance superior to that of GCC. Through long-term development and iteration, GCC, Clang, and LLVM have become mature compilers in the industry.
Clang is designed as an API from its inception, allowing it to be reused by source analysis tools, refactoring, IDEs (etc) as well as for code generation. GCC is built as a monolithic static compiler, which makes it extremely difficult to use as an API and integrate into other tools.
This isn't quite as straightforward as it might seem. A lambda that captures k
by copy is mostly equivalent to a struct object whose closure type has a member named k
, and with an operator()
whose definition uses the specified parameters and body. If that were technically true, sure, we know that a function parameter hides a class member.
Except that's not how the Standard actually defines lambdas. Instead, it says that any entity captured by value corresponds to an unnamed member of the closure type. In the lambda body, name lookup looks in the lambda's enclosing scope, not the scope of the closure type. If that name lookup finds an entity captured by copy, the compiler must internally transform that usage of the name to a usage of the unnamed member instead. In C++11 and C++14, these rules didn't clearly specify how lambda parameter names fit into that name lookup scheme, and as a result, different compilers and compiler versions didn't agree on behavior in cases like this where a captured entity and a lambda parameter had the same name.
With Defect Resolution 2211, C++17 solved the issue by just making it illegal:
[expr.prim.lambda.capture]/5:
If an identifier in a simple-capture appears as the declarator-id of a parameter of the lambda-declarator's parameter-declaration-clause, the program is ill-formed. [ Example:
void f() { int x = 0; auto g = [x](int x) { return 0; } // error: parameter and simple-capture have the same name }
-- end example ]
(See also the same paragraph in the current draft mirror.)
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