Let's consider this code:
int main()
{
int a = 1;
auto f1 = [a]() {
int a = 10;
return a;
};
auto f2 = []() {
int a = 100;
return a;
};
return a + f1() + f2();
}
When using flag -Wshadow
with gcc (tested on 10.2), we get these warnings:
<source>:26:13: warning: declaration of 'a' shadows a lambda capture [-Wshadow]
6 | int a = 10;
<source>:21:13: warning: declaration of 'a' shadows a previous local [-Wshadow]
11 | int a = 100;
I understand the first case, where we explicitly capture a
, and thus are shadowing the original local. However, the second case is interesting, because if we remove declaration int a = 100;
we get a compile error (= error: 'a' is not captured: return a;
). Doesn't that "prove" that the declaration is not in the same scope as the original local, and thus we are not actually shadowing anything? Hence my question, whether the warning (for the second case) is indeed valid, or whether gcc is being a bit too strict here?
Variable shadowing could be avoided by simply renaming variables with unambiguous names. We could rewrite the previous examples: The inner scope has access to variables defined in the outer scope.
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking.
When inside the nested block, there's no way to directly access the shadowed variable from the outer block. However, because global variables are part of the global namespace, we can use the scope operator (::) with no prefix to tell the compiler we mean the global variable instead of the local variable.
You are correct, lambda a
doesn't shadow main::a
because main::a
isn't captured in the lambda, thus is not on scope there.
However I think about what the purpose of the shadow warning is: to avoid programmer confusion. If a long body of code if the programmer sees the outer declaration, but doesn't see the inner declaration he or she may incorrectly assume that a use of the inner variable refers to the outer variable. And this possible confusion still applies here, even if the variable doesn't tehnically shadow the outer one.
I don't know if this is the intention of the warning or if it is a bug. Or even if that is a compelling enough reason to have a warning even a differently worded one. Shadow warning are problematic anyways. You can find a lot of discussions and bug reports about shadow warning that even if tehnically correct are considered harmful.
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