https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114450
Bug ID: 114450
Summary: -Wunused-but-set-variable false positive in lambda
using another static auto lambda
Product: gcc
Version: 13.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: olof.gullnas at gmail dot com
Target Milestone: ---
Created attachment 57798
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57798&action=edit
Code to produce warning
Using g++ where "g++-13 -v" print a last line with:
gcc version 13.2.1 20230912 [revision b96e66fd4ef3e36983969fb8cdd1956f551a074b
(SUSE Linux)
I compiling with g++-13 -Wall -Wextra.
This program gets a warning
variable ‘lambda_2’ set but not used [-Wunused-but-set-variable]
The variable IS used, so I think this is a "false positive"
The code is stripped down from a MUCH larger example so this code
does not do anything useful...
//#include // required if std::for_each or std::ranges::for_each is
used
#include // for "trace printouts", not needed if printouts are
removed
#include
// a MUCH simplified version of std::for_each
template
void foreach(I b, I e, F f)
{
for (auto ii= b; ii != e; ++ii)
{
f(*ii);
}
};
int main (int, char**)
{
std::vector v{ 2 };
// constexpr is not needed for warning to appear. static probably is
// If not static and "lambda_2" captured by lambda_1 then no
// warning. Likely that static variable being available
// to lambda_1 without explicit capture is required for warning to
// appear.
// A lambda that returns another lambda. A -Wunused-but-set-variable
// warning is generated. It IS used in lambda_1.
static /*constexpr*/ auto lambda_2 = [](auto id) {
std::cout << "lambda_2" << "\n";
return [id]( auto f) {
std::cout<< "lambda gen by lambda_2\n";
return f == id;
};
};
auto lambda_1 = []( auto& id)
{
auto f = lambda_2(id); // lambda_2 used here
// to avoid warning about unused f... If pgm executed without
// following line, lambda_2 is still called/used.
std::cout << f(2) << "\n";
};
#if 1
// using a local simplistic foreach template gives the warning
foreach(v.begin(), v.end(), lambda_1);
// as does using lambda_1 in std::for_each(...)
//std::for_each( v.begin(), v.end(), lambda_1); // requires #include
#else
// if std::for_each algorithm is replaced by a simple loop or
// a direct call to lambda_1 the warning disappears
//for ( auto it = v.begin(); it != v.end();++it) // no warning
//lambda_1(*it);
// or
//lambda_1(v[0]); // no warning
//
// A bit more surprising is that using
// std::ranges::for_each also avoids the warning!
std::ranges::for_each(v, lambda_1); // no warning, requires #include
#endif
}