I encountered an unusual pair of compiler warnings that seem mutually contradictory. Here's the code I've written:
#include <functional>
#include <iostream>
namespace {
std::function<void()> callback = [] {
void theRealCallback(); // Forward-declare theRealCallback
theRealCallback(); // Invoke theRealCallback
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
callback();
}
In other words, I define a lambda function in an unnamed namespace that forward-declares a function defined later in that unnamed namespace.
When I compile this code with g++ 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1), I get these two warnings:
CompilerWarningsNamespace.cpp:6:10: warning: ‘void {anonymous}::theRealCallback()’ used but never defined
void theRealCallback();
^~~~~~~~~~~~~~~
CompilerWarningsNamespace.cpp:10:8: warning: ‘void {anonymous}::theRealCallback()’ defined but not used [-Wunused-function]
void theRealCallback() {
^~~~~~~~~~~~~~~
This is strange, because the first warning says that I'm using a function without defining it, and the second warning says that I'm defining a function without using it.
Running this program indeed produces the output
theRealCallback was called.
and the program terminates normally.
Interestingly, these warnings go away if instead of using an unnamed namespace, I give the namespace a name, as shown here:
#include <functional>
#include <iostream>
namespace NamedNamespace {
std::function<void()> callback = [] {
void theRealCallback();
theRealCallback();
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
NamedNamespace::callback();
}
The modified version of the code, like the original code, prints out a message indicating that theRealCallback
was invoked.
Can someone explain why I'm getting these warnings? My guess is that this has something to do with the forward-declaration of the function in the lambda function as being interpreted as something other than the later function that appears in the unnamed namespace, but if that's the case I'm not sure I see why this links in the end and why I'm getting those warnings.