I haven't been following GCC, so I need to thank Jason for forwarding
this issue to me.
I just read through the messages on the list, and had some more comments:
+ /* relayout again -- to allow for implicit
+ * parameters to have been added to the capture if it was a
+ * 'default capture' -- note that this would not be necessary if
+ * the stack-pointer variant was implemented -- since the layout
+ * would be known.
+ * Relayingout here might have nasty effect if one were to query
+ * sizeof *this from within the body -- would that even be
+ * possible -- *this would refer to the lambda or the enclosing
+ * class instance -- if there was one.???
+ *
+ * NOTE: I think this is a redefinition error; I'm just faking that
+ * it isn't by clearing the size node... need to use stack pointer
+ * method. But that will likely bring its own issues -- not with
+ * class layout though.
+ */
+ TYPE_SIZE (type) = NULL_TREE;
+ finish_struct_1 (type);
Relaying out the class after the lambda body was parsed is something I
had attempted to do, but possibly failed at. It will absolutely need to
be done.
The way 'default reference capture' is implemented on the lambda branch seems
to be kind of reactive. I would expect
that inheriting the stack somehow (maybe using just a stack pointer) would be
better but without more investigation I
don't know if that is possible or how one would go about doing it.
This won't be suitable in the general case, because of the copy default
capture [=]. Implicit captures will have to be reactive.
/*
* Rather than looping through the identifiers used in the scope of
* the lambda and synthesizing individual captures of them, it would
* be better to ref the stack frame as transparently as possible...
* e.g. given just three ints i, j and k in scope:
* Instead of transforming:
*
* [&] { i = 1; j = 2; k = 3; };
*
* into
*
* [&i,&j,&k] { i = 1; j = 2; k = 3; };
*
* and thus storing three pointers to int, transform it into:
*
* [sp=enclosing-stack-pointer] { var-from-stack(i,sp) = 1;
* var-from-stack(j,sp) = 2;
* var-from-stack(k,sp) = 3; };
*
* and only store one pointer.
This is preferred for reference default captures, but I was not familiar
with stack pointer mechanics in GCC. I just wanted to get something
working first that could be improved later.
* I don't know if its possible but it may be possible to 'append'
* the lambda's stack to the existing scope rather than creating a
* new constrained scope -- from a logical point of view.
Again, this is not suitable to the general case because a lambda can
outlast its enclosing scope.
My motivation for investigating is that I consider constraining lambdas to be
monomorphic significantly reduces their
usefulness. I'm sure there are many good reasons why the committee decided
that it was the way to go.
I don't think it handicaps lambdas as much as some may believe, but
still wanted polymorphic lambdas as well. There were just too many
issues with deduction. When I last left the discussion, the biggest
issue in my opinion was concept map dropping. The workaround made the
deduction algorithm intimidatingly complex.
The following program generates the expected code and runs correctly.
auto f = [&] <typename T, typename U> (T n, T const& m, U u) { i = ++n; j =
u(++n); k = ++n; };
This is exciting. The main thing I failed to add was dependent type
support, so I want to check this out. (I need to register a new ssh key)
- John