As we know an anonymous union is an unnamed union definition that does not simultaneously define any variables. And members of an anonymous union are injected in the enclosing scope. But are there any restrictions on capturing these members in lambda expressions?
In the following example program
int main() {
union {
int x{0};
char y[4];
};
// error everywhere
//[=]() { return x; };
//[&]() { return x; };
// ok in GCC only
[x]() { return x; };
[&x]() { return x; };
// ok in all
[x=x]() { return x; };
[&x=x]() { return x; };
}
all compilers refuse to make implicit capture (both by value [=]
and by reference [&]
). E.g. Clang's error is
unnamed variable cannot be implicitly captured in a lambda expression
As to explicit capture (both by value [x]
and by reference [&x]
), here compilers diverge. MSVC prints the same error:
error C3492: 'x': you cannot capture a member of an anonymous union
The error from Clang changes and becomes less clear:
'x' in capture list does not name a variable
And GCC permits explicit capture without any warning. Online demo: https://gcc.godbolt.org/z/Ghq66rjfW
Which compiler is right here?
The defect report and resolution of CWG 1612 means that it is not allowed to capture any member of an anonymous union, neither by copy or reference, neither implicitly nor explicitly.
See e.g. [expr.prim.lambda.capture]/10 and [expr.prim.lambda.capture]/12 in the post-C++20 draft N4868:
[...] A member of an anonymous union shall not be captured by copy.
[...] A bit-field or a member of an anonymous union shall not be captured by reference.