c++ - Capturing a Lambda's static in a Nested Lambda -


in this answer use code:

std::vector<std::vector<int>> imat(3, std::vector<int>(10));  std::for_each(imat.begin(), imat.end(), [&](auto& i) {     static auto row = 0;     auto column = 0;     std::transform(i.begin(), i.end(), i.begin(),          [&](const auto& /*j*/) {             return row * column++;      });       ++row;  }); 

but notice misbehavior in capturing static auto row depending upon compiler.

clang 3.7.0 yields:

0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18

gcc 5.1.0 yields:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

and visual studio 2015 gives me compile time error:

an internal error has occurred in compiler.

if change capture nested capture capture row explicitly compiler error:

identifier in capture must variable automatic storage duration declared in reaching scope of lambda

am allowed capture static in nested lambda? seems legit, there many problems!

edit:

fozi pointed out can visual studio 2015 compile , give same output clang 3.7.0 if change nested lambda's parameter type const auto& const int&. seems unrelated, works.

this doesn't work if try capture row explicitly. in case still compiler error:

identifier in capture must variable automatic storage duration declared in reaching scope of lambda

i've reported visual studio 2015 bug here: https://connect.microsoft.com/visualstudio/feedback/details/1930409/capturing-a-lambdas-static-in-a-nested-lambda

an internal compiler error(ice) bug.

we don't need capture variables of static storage duration need capture automatic variables odr-used. draft c++ standard section 5.1.2:

the lambda-expression’s compound-statement yields function-body (8.4) of function call operator, but purposes of name lookup (3.4), determining type , value of (9.3.2) , transforming idexpressions referring non-static class members class member access expressions using (*this) (9.3.1), the compound-statement considered in context of lambda-expression.

so row should visible within inner lambda and:

[...]if lambda-expression or instantiation of function call operator template of generic lambda odr-uses (3.2) or variable automatic storage duration reaching scope, entity shall captured lambda-expression.[...]

capture required this , variables of automatic storage duration if odr-used , can see explicit capture defined automatic variables or this:

the identifier in simple-capture looked using usual rules unqualified name lookup (3.4.1); each such lookup shall find entity. entity designated simple-capture said explicitly captured, and shall or variable automatic storage duration declared in reaching scope of local lambda expression.

for both visual studio , gcc match results of clang can move row out global namespace, see live gcc. fozi points out changing const auto& /*j*/ const int& /*j*/ makes start working.

it looks gcc accepts explicit capture of non-automatic variables extension , explicitly capturing row example [&, &row](const auto & ) still produces zeros.

further gcc if move definition row main see following error (see live):

/tmp/cchzwtqi.s: assembler messages: /tmp/cchzwtqi.s:1572: error: symbol `_zl3row' defined 

which seems compiler error me.

i don't see portion of standard make original program ill-formed. nor should changing auto int make difference , non of changes introduced polymorphic lambda proposal seem explain difference either.


Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -