Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a lambda capturing nothing access global variables?

int n;     int main() {     [](){ n = 0; }(); // clang says "ok"      int m;     [](){ m = 0; }(); // clang says "not ok" } 

I just wonder:

If the lambda captures nothing, is it allowed to access global variables as per the C++ standard?

like image 940
xmllmx Avatar asked May 07 '17 03:05

xmllmx


People also ask

Can lambda function access global variables?

The lambda's execution takes place in a fresh local context with only its two local parameter variables, x and y ; it doesn't have access to global variables.

Can global variables be accessed anywhere?

Variables that are created outside of a function are known as Global Variables . A global variable is one that can be accessed anywhere . This means, global variable can be accessed inside or outside of the function.

Does lambda capture reference by value?

The mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y , which the lambda expression captures by value. Because the lambda expression captures the original variables x and y by value, their values remain 1 after the lambda executes.

What does it mean to lambda capture this?

The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.


2 Answers

Yes, sure. Normal name lookup rules apply.

[expr.prim.lambda]/7 ... for purposes of name lookup ... the compound-statement is considered in the context of the lambda-expression.

Re: why local variables are treated differently from global ones.

[expr.prim.lambda]/13 ... If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses (3.2) this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.

[expr.prim.lambda]/9 A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression... The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the innermost enclosing function and its parameters.

In your example, m is a variable with automatic storage duration from the lambda's reaching scope, and so shall be captured. n is not, and so doesn't have to be.

like image 63
Igor Tandetnik Avatar answered Oct 10 '22 20:10

Igor Tandetnik


Actually the [](){ n = 10; }(); doesn't capture anything, it uses the global variable instead.

int n;     int main() {     [](){ n = 10; }(); // clang says "ok"     std::cout << n; // output 10 } 

See capture-list in Explaination

capture-list - a comma-separated list of zero or more captures, optionally beginning with a capture-default.

Capture list can be passed as follows (see below for the detailed description):

  • [a,&b] where a is captured by copy and b is captured by reference.
  • [this] captures the current object (*this) by reference
  • [&] captures all automatic variables used in the body of the lambda by reference and current object by reference if exists
  • [=] captures all automatic variables used in the body of the lambda by copy and current object by reference if exists
  • [ ] captures nothing
like image 25
Jiahao Cai Avatar answered Oct 10 '22 20:10

Jiahao Cai