| Summary: | Wshadow and lambda captures | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Nathan Sidwell <nathan> |
| Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | UNCONFIRMED --- | ||
| Severity: | enhancement | CC: | arnaud02, eb, egallager, lvella, mika.fischer, paul.skeptic, sjames, webrown.cpp |
| Priority: | P3 | Keywords: | c++-lambda, diagnostic |
| Version: | 7.0 | ||
| Target Milestone: | --- | ||
| See Also: |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112309 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121553 |
||
| Host: | Target: | ||
| Build: | Known to work: | ||
| Known to fail: | Last reconfirmed: | ||
| Bug Depends on: | |||
| Bug Blocks: | 105828, 54367 | ||
| Attachments: |
example
simple test case |
||
If I may, I think at least this case
// Warning considered erroneous
// There is no default capture to get at the outer object
void haveWarningBad (int x) {
[] { int x; };
}
should be fixed not to produce any warnings.
Created attachment 46658 [details]
simple test case
Build with
g++-9 test.cc -Wshadow -o test
This defect makes -Wshadow=local difficult to use with immediately invoked lambda expressions. For instance,
gcc 9.2 compiles:
#include <array>
auto f(int s) {
const auto v = []{
std::array<int,2> v = {1, 2};
return v;
}();
return v.size();
}
with:
source>: In lambda function:
<source>:4:25: warning: declaration of 'v' shadows a previous local [-Wshadow]
4 | std::array<int,2> v = {1, 2};
| ^
<source>:3:14: note: shadowed declaration is here
3 | const auto v = []{
| ^
Can confirm this also happens with gcc 10.2.0. still in 13.3 Still not fixed in 15.2. https://godbolt.org/z/zeed4KhM1 |
Created attachment 40647 [details] example -Wshadow warnings have a confusing interaction with lambda captures. 1) The names of init lambda captures are not checked. 2) local names are checked regardless of whether there is a default capture to make an outer object accessible The original report also mentioned the following case: T x; [=, x = std::move(x)] {}; if T is a non-copyable type, the default = capture couldn't capture it. IMHO such nuance shouldn't affect whether or not this gives a warning (so it should warn). I think it clear that #1 should be checked, but I can see arguments for and against #2. I think of name hiding as (almost) a syntactic check, and whether an object can be captured is more of a semantic check.