Why does this code compile with GCC (4.9 and 5+), but not with clang (3.5-3.9)?
void test(const int&) { }
int main() {
const int x = 42;
auto f = []{ test(x); };
}
I have some vague idea that the discrepancy has to do with ODR (One Definition Rule) usage, but I don't understand that well enough to figure out what's going on here.
x
is odr-used because it's bound to a reference (test
's parameter). It therefore must be captured ([expr.prim.lambda]/13):
If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses ([basic.def.odr])
this
or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.
Violations of this rule, like all other rules in the standard that doesn't say "no diagnostic required" or "undefined behavior", require a diagnostic.
GCC, unfortunately, performs constant folding too early, before it could tell whether it's an odr-use or not. This can lead to problems such as [&]()->const int & { return x; }
returning a dangling reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With