Section 5.1.2 p10 of the ISO C++11 specification states:
The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression. An entity (i.e. a variable or this) is said to be explicitly captured if it appears in the lambda-expression’s capture-list.
This seems to imply that a lambda cannot capture a file scope variable. For example, this program should be illegal:
#include <iostream>
int x = 13;
int main()
{
auto l = [](){ return x; };
std::cout << l() << std::endl;
return 0;
}
However, g++
4.7.1 produces the result I expect:
$ g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -std=c++11 lambda.cpp
$ ./a.out
13
But clang
3.0 crashes:
$ clang --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: i386-pc-linux-gnu
Thread model: posix
$ clang -std=c++11 lambda.cpp
0 libLLVM-3.0.so.1 0xb70a59e8
1 libLLVM-3.0.so.1 0xb70a5f34
2 0xb775d400 __kernel_sigreturn + 0
3 clang 0x0869f2e9 clang::Sema::DeduceAutoType(clang::TypeSourceInfo*, clang::Expr*, clang::TypeSourceInfo*&) + 73
<snip>
Is my program illegal or not? If it is illegal, what is the rationale for the proscription on capturing file scope variables?
For purposes of name lookup, the body of the lambda is considered to be in the context of the lambda expression. That is, name lookup happens as if you used the name outside the lambda. See [expr.prim.lambda]/7. For example:
Now, you need to capture variables of automatic storage duration. I guess this makes it a bit less error-prone, as you can copy and return lambdas, so that the automatic variables have been destroyed when the lambda is called:
Of course, this problem does not appear for variables with static storage duration.
Specifically, [expr.prim.lambda]/12 says:
Non-automatic variables will be found by name lookup as well, but are not affected by this rule. You can use them without capturing.
N.B. the odr-use relaxation allows some uses of automatic variables w/o capturing them, such as: